shapi
, or shell API, is a Lua module which implements some kind of
eDSL1 to work with the shell/CLI2 environment. It depends on
luaposix.
The incentive is to have an alternative to a shell language like bash, as an
API.
E.g. for scripting purposes, if one already uses Lua at the heart of its
methodology, or to be embedded into an existing application.
Overview
local sh = require "shapi"
print("HEAD: "..sh:git("rev-parse", "HEAD"))
print(sh:__in("foo/bar.txt"):md5sum())
sh:__p("my-command", "--foo", "bar"):__out("foo/bar.txt")()
sh:sleep(2):__return()
sh:sleep(2)()
Install
See src/
, rockspecs/
or
luarocks.
API
A command object is created and then chain methods are applied to it. This
chaining pattern is similar to bash pipes, making :
behave like |
. For
most methods, it means linking stdout from the previous step to stdin of
the next one while keeping stderr of the parent process (unless __err
is
used).
Methods will directly spawn sub-processes as they are called, there is no build phase of the command.
Special methods start with __
and other strings will be interpreted as shell
process names.
Calling on the command object is an alias to __return(...)
. String conversion
and concatenation will call __return()
.
Note: The chain starts from the module, the first method is called on it,
but the self
parameter will be replaced with the command object.
__str_in(data)
Input raw string data into the chain (create a new process).
__in(file, [mode])
Input a file into the chain.
If file
is a string, file, [mode]
is the path and mode for io.open()
. The
mode
defaults to rb
.
If file
is a number, it indicates a file descriptor3.
__out(file, [mode])
Output the chain to a file (create a new process).
If file
is a string, file, [mode]
is the path and mode for io.open()
. The
mode
defaults to wb
.
If file
is a number, it indicates a file descriptor3.
__err(file, [mode])
Setup stderr for subsequent processes of the chain.
If file
is a string, file, [mode]
is the path and mode for io.open()
. The
mode
defaults to wb
.
If file
is a number, it indicates a file descriptor3.
Example: Discard stderr
local cmd = sh:__err("/dev/null"):cat("foo/missing.txt")
local ok, out = pcall(cmd)
__p(name, ...)
Chain a shell process.
Can be used to chain a shell process with a name which cannot be represented with a Lua name/identifier.
- name: shell process name/path (see luaposix execp)
- ...: process arguments
<shell-process>(...)
Alias for __p(<shell-process>, ...)
.
__lua(fproc, ...)
Chain a Lua function (create a new process).
- fproc: Lua function
- ...: function arguments
Example: Implementation of __str_in
-- __str_in is equivalent to:
sh:__lua(function() assert(io.stdout:write(data)) end)
__wait()
Wait/end the command.
It waits on the command processes and returns the command internal state.
state (table):
- output: unprocessed final output (stdout), string
- children: list of children
{}
(follows the chain order)- pid
- kind:
"exited"
,"killed"
or"stopped"
- status: exit status, or signal number responsible for
"killed"
or"stopped"
__return([mode])
Return/end the command.
It waits on the command processes, propagates exit errors or returns the final output (stdout) as a string.
By default, trailing new lines are removed, but this can be disabled using the mode parameter.
- mode: string,
"binary"
to prevent processing of the output
__do()
Do/end the command (outputs to stdout).
It waits on the command processes and propagates exit errors.
__(f, ...)
Chain custom method.
- f(self, ...): method
- ...: method arguments
Example: Abstraction of multiple steps
local function my_md5sum(self, file)
return self:md5sum(file):cut("-d", " ", "-f", 1)
end
print(sh:__in("foo/bar.txt"):__(my_md5sum))
print(sh:__(my_md5sum, "foo/bar.txt"))