Tiny library for shell scripting with Lua (inspired by Python's sh module).
Via luarocks:
luarocks install --server=http://luarocks.org/dev luash
Or just clone this repo and copy sh.lua into your project.
Every command that can be called via os.execute can be used a global function. All the arguments passed into the function become command arguments.
require('sh')
local wd = tostring(pwd()) -- calls `pwd` and returns its output as a string
local files = tostring(ls('/tmp')) -- calls `ls /tmp`
for f in string.gmatch(files, "[^\n]+") do
print(f)
end
If command argument is a table which has a __input
field - it will be used as
a command input (stdin). Multiple arguments with input are allowed, they will
be concatenated.
The each command function returns a structure that contains the __input
field, so nested functions can be used to make a pipeline.
Note that the commands are not running in parallel (because Lua can only handle one I/O loop at a time). So the inner-most command is executed, its output is read, the the outer command is execute with the output redirected etc.
require('sh')
local words = 'foo\nbar\nfoo\nbaz\n'
local u = uniq(sort({__input = words})) -- like $(echo ... | sort | uniq)
print(u) -- prints "bar", "baz", "foo"
Pipelines can be also written as chained function calls. Lua allows to omit parens, so the syntax really resembles unix shell:
-- $ ls /bin | grep $filter | wc -l
-- normal syntax
wc(grep(ls('/bin'), filter), '-l')
-- chained syntax
ls('/bin'):grep(filter):wc('-l')
-- chained syntax without parens
ls '/bin' : grep filter : wc '-l'
You can use sh.command
to construct a command function, optionally
pre-setting the arguments:
local sh = require('sh')
local truecmd = sh.command('true') -- because "true" is a Lua keyword
local chrome = sh.command('google-chrome') -- because '-' is an operator
local gittag = sh.command('git', 'tag') -- gittag(...) is same as git('tag', ...)
gittag('-l') -- list all git tags
sh
can be used as a function as well, it's an alias to sh.command()
Each command function returns a table with __exitcode
and __signal
fields.
Those hold the exit status and signal value as numbers. Zero exit status means
the command was executed successfully.
SInce f:close()
returns exitcode and signal in Lua 5.2 or newer - this will
not work in Lua 5.1 and current LuaJIT.
Key-value arguments can be also specified as argument table pairs:
require('sh')
-- $ somecommand --format=long --interactive -u=0
somecommand({format="long", interactive=true, u=0})
It becomes handy if you need to toggle or modify certain command line argumnents without manually changing the argumnts list.
Code is distributed under the MIT license.