Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

lpath - Path utils for Lua

CICoverage Status

lpath is a lfs-like Lua module to handle path, file system and file informations.

This module is inspired by Python's os.path and pathlib module. It split into 4 parts:

  • path: main module, pathlib style path operations.
  • path.fs: fs specific operations, folder walking, file operations, etc.
  • some constants about path literals.
  • path.env set/get environment variables, and expand env vars in path.

All routines in this module which accept ... for parameters means you could pass any count of string as arguments. All string will joined into a single path, just as pass all arguments to path(...), and pass the resulting path string to the routine.

All routines may returns nil, error for error case. if you want raise error to Lua, use assert(...) for routines.



routine return value description
path(...) string return joined normalized path string.
path.ansi() none set path string encoding to local code page.
path.ansi(number) none set the code page number for path string encoding.
path.ansi(string) string convert UTF-8 string to current code page encoding.
path.utf8() none set path string encoding to UTF-8.
path.utf8(string) string convert current code page encoding string to UTF-8.
path.alt(...) string return joined normalized path string using alternative sep.
path.abs(...) string returns the absolute path for joined parts.
path.rel(path[, dir]) string returns the relation path for dir (default for current work directory).
path.fnmatch(string, pattern) boolean returns whether the pattern matchs the string.
path.match(path, pattern) boolean returns as path.fnmatch, but using Python path matching rules. string returns the drive part of path.
path.root(...) string returns the root part of path. (\ on Windows, / or // on POSIX systems.)
path.anchor(...) string same as .. path.root(...)
path.parent(...) string returns the parent path for path. string returns the file name part of the path.
path.stem(...) string returns the file name part without suffix name of the path.
path.suffix(...) string returns the suffix name of the path.
path.suffixes(...) iteraotr returns a idx, suffix iterator to get suffix names of the path. iterator returns a idx, part iterator to get parts in the path.
path.exists(...) boolean returns whether the path is exists in file system (same as fs.exists())
path.resolve(...) string returns the path itself, or the target path if path is a symlink.
path.cwd() string fetch the current working directory path.
path.bin() string fetch the current executable file path.
path.isdir(...) boolean returns whether the path is a directory.
path.islink(...) boolean returns whether the path is a symlink.
path.isfile(...) boolean returns whether the path is a regular file.
path.ismount(...) boolean returns whether the path is a mount point.


routine return value description
fs.dir(...) iterator returns a iterator filename, type to list all child items in path.
fs.scandir(...[, depth]) iterator same as fs.dir, but walk into sub directories recursively.
fs.glob(...[, depth]) iterator same as fs.scandir, but accepts a pattern for filter the items in directory.
fs.chdir(...) string change current working directory and returns the path, or nil for error.
fs.mkdir(...) string create directory.
fs.rmdir(...) string remove empty directory.
fs.makedirs(...) string create directory recursively.
fs.remvoedirs(...) string remove all items in a directory recursively.
fs.unlockdirs(...) string add write perimission for all files in a directory recursively.
fs.tmpdir(prefix) string create a tmpdir and returns it's path
fs.ctime(...) integer returns the creation time for the path.
fs.mtime(...) integer returns the modify time for the path.
fs.atime(...) integer returns the access time for the path.
fs.size(...) integer returns the file size for the path.
fs.touch(...[, atime[, mtime]]) string update the access/modify time for the path file, if file is not exists, create it.
fs.remove(...) string delete file.
fs.copy(source, target) boolean copy file from the source path to the target path.
fs.rename(source, target) boolean move file from the source path to the target path.
fs.symlink(source, target[, isdir]) boolean create a symbolic link from the source path to the target path.
fs.exists(...) boolean same as path.exists
fs.getcwd() string same as path.cwd()
fs.binpath() string same as path.bin(){dir/link/file/mount} string same as correspond routines in path module.


These functions will return a iterator that yields filename, type pair. The type could be:

  • "file" a file name
  • "dir" a dir the will not walk into it.
  • "in" a dir that will walk into it, i.e. the next iteration will yields the content in this folder.
  • "out" a dir that completed walk.

If you pass a number argument as the last argument of fs.scandir()/fs.glob(), this number argument will be treat as the limit of walking. e.g. fs.scandir("foo", 1) will walks into all subdirectory/files in "foo", but not contents in subdirectories.

-- assume folder "foo" has this struture:
-- - foo
--   |- bar
--      |- bar.txt
--   |- foo.txt
-- the code below:
for fn, ty in fs.scandir("foo", 1) do
  print(fn, ty)
-- will prints:
-- foo in
-- bar dir
-- foo.txt file
-- foo out

fs.glob() accepts a path thats contains patterns in it. But patterns in drive part will be ignored. e.g. the pattern likes "*:/foo.txt" in Windows will yields empty results.

A empty pattern ("") is not allowed.

If a pattern contains "**", the fs.glob() will walks into all current subdirectories to find a match after "**", e.g. "**/*.txt" will yields all .txt files in any levels of subdirectories of current folder.

If the pattern ends with "**", all subdirectories, but not files, will returnd.

Some examples:

-- assume same struture of folder "foo" above.
local function collect(pattern) do
    local t = {}
    for fn in fs.glob(pattern) do
      t[#t+1] = fn
collect "*.txt"    -- returns {"foo/foo.txt"}
collect "**/*.txt" -- returns {"foo/foo.txt", "foo/bar/bar.txt"}
collect "**"       -- returns {"foo/bar"}


routine return value description
env.get(key) string fetch a environment variable value.
env.set(key, value) string set the environment variable value and returns the new value.
env.expand(...) string return a path that all environment variables replaced.
env.uname() string, ... returns the informations for the current operation system. has several constants about current system:

  • platform:
    • "windows"
    • "linux"
    • "macosx"
    • "android"
    • "posix"
  • sep: separator of directory on current system. It's "\\" on Windows, "/" otherwise.
  • altsep: the alternative directory separator, always "/".
  • curdir: the current directory, usually ".".
  • pardir: the parent directory, usually "..".
  • devnull: the null device file, "nul" on Windows, "dev/null" otherwise
  • extsep: extension separator, usually ".".
  • pathsep: the separator for $PATH, ";" on Windows, otherwise ":".


Same as Lua's License.


See here:


a OS specified path manipulation module for Lua







No packages published

Contributors 4