execline
Software
skarnet.org
The execlineb program
execlineb reads and executes a script.
It is a command launcher: it reads a file, turns that file into a command line,
then executes into that command line.
Interface
execlineb [ -q | -w | -W ] [ -p | -P | -S nmin | -s nmin ] [ -e ] -c script [ args... ]
or
execlineb [ -q | -w | -W ] [ -p | -P | -S nmin | -s nmin ] [ -e ] scriptfile [ args... ]
or in an executable file:
#!/command/execlineb [ -qwWpPSnmin ]
script
Parsing phase.
- execlineb reads and parses the script it is given.
It exits 100 on a syntax error and 111 on a temporary error.
It makes an argv, i.e. a system command line, with the
parsed script. If the argv is empty, execlineb
exits 0.
Environment management phase.
- Pushing the current stack frame. If none of the
-p, -P, -S or -s options are set:
execlineb pushes
the current positional parameters, i.e. environment variables that
start with #, 0, 1, ..., 9.
To get the previous values back, use
emptyenv -P.
- Setting the new stack frame. If none of the -P,
-S or -s options are set:
- execlineb sets the # environment variable to
the number n of args it is given.
- It sets the 0 environment variable to the name
of the script - or to the execlineb invocation name
if the -c option is used.
- It sets the 1, 2, ... n
environment variables to the different args.
Execution phase.
- execlineb executes into the argv it
has built from the script.
There is only one command line for the
whole script: the execlineb binary is a launcher,
whose sole purpose is to execute into that command line. It does
not stay in memory like a traditional interpreter would.
Options
- -e : this option is ignored. This is meant to support
the use of execlineb in conjuction with programs that invoke
$SHELL -ec script; the effect of /bin/sh -e
can be natively replicated in execline scripts if you use the
if command instead of the
foreground command.
- -c script : execute script, do not
look for a file.
See below for the other options.
Syntax of scripts
An execlineb script is a string that must not contain the null character.
execlineb parses it and divides it into words.
The parser recognizes the following components:
- whitespace is defined as spaces, tabs, newlines and
carriage returns. Words are always separated by whitespace.
- A quoted string begins with a doublequote (")
and ends with another doublequote. Quoted doublequotes must be prefixed
by a backslash (\). Quoted strings always evaluate to exactly
one word. For instance, "" evaluates to the empty word.
- The \a, \b, \t, \n, \v,
\f, and \r sequences are recognized in quoted
strings, and are converted to the ASCII numbers 7, 8, 9, 10, 11, 12 and
13 respectively.
- Inside a quoted string, backslashed
newlines disappear completely.
- \0xab sequences are recognized in quoted strings
and evaluate to ASCII hexadecimal number ab.
- \0abc sequences are recognized in quoted strings
and evaluate to ASCII octal number abc. abc must not
be greater than 377, or evaluate to 0.
- \abc sequences are recognized in quoted strings
and evaluate to ASCII decimal number abc. a must not
be zero. abc must not be greater than 255, or evaluate to 0.
- A comment starts with a # and ends with the line. Comments
are not recognized inside quoted strings.
- Anything else is an unquoted string, that can evaluate to
zero or more words.
- Any character can be escaped in unquoted strings by prepending
it with a backslash. It works the same way in quoted strings, except
for the special sequences described above.
- As a special case, an unquoted backslash at the end of a line, or at
the end of the input, is ignored. This is to make it easier to copy
execline fragments from a shell script.
You can see an example of distinct execlineb components
here.
In addition to that simple lexing,
execlineb performs the following higher-level parsing:
- A word consisting of a single opening brace ({)
increments an internal level counter, blevel, and disappears from the
argv. Quoted open braces do not have that behaviour.
- A word consisting of a single closing brace (})
decrements blevel, and is replaced with the empty word.
Quoted closing braces do not have that behaviour.
- If execlineb finds that braces are unmatched (i.e.
blevel goes below 0 during the parsing, or is not 0 at the end
of the script), it exits 100 with an error message.
- execlineb automatically quotes
blocks. Which means that every time it
finds a word, it prepends it with blevel spaces.
For proper execution, the sequence of words must follow
the execline grammar.
Options for block syntax checking
External execline commands that read blocks, like
foreground, use the EXECLINE_STRICT
environment variable: if it is set to 1, they will print a warning message
on stderr if they find their blocks not to be properly quoted. If it is set
to 2, they will also die. If it is set to 0, or unset, they won't complain
at all.
Normally the EXECLINE_STRICT environment variable is
inherited from the caller. You can
force it unset, set to 1, or set to 2 by giving respectively the
-q, -w or -W option to execlineb.
The EXECLINE_STRICT variable (as well as the -q,
-w and -W options to execlineb) will also modify
the behaviour of the -S nmin and -s nmin
options when execlineb is called with less than nmin
positional parameters:
- If EXECLINE_STRICT is 0: the script will run
silently, and missing positional parameters, up to nmin, will
be substituted with the empty word.
- If EXECLINE_STRICT is 1 or unset: same, but the script will
print a warning message rather than run silently.
- If EXECLINE_STRICT is 2: the script will exit with an
error message.
Options for environment management
Normally, execline scripts are reentrant: environment variables
potentially overwritten by execlineb, such as # or
0, are
pushed. This is the standard, safe
behaviour. Nevertheless, it is rather costly, and may be unneeded for
small scripts: for those cases, execline comes with two options
that bypass the environment management. Be warned that the purpose
of these options is optimization, and you should not
use them if you're not familiar with the way execlineb uses the
environment to store positional parameters. Alternatively, there's also
an integrated substitution mechanism that doesn't make use
of the environment at all.
- The -p option will bypass the
push phase: the current frame of positional
parameters will be overwritten. The script will not be
reentrant.
- The -P option will bypass positional parameter handling
completely: the environment will not be pushed, and positional
parameters will be ignored. execlineb -P -c "script" is
equivalent to, but more efficient than, execlineb -c
"emptyenv -P script". You should use the -P option
only in standalone scripts that take no arguments, such as
s6's or
runit's run scripts.
- The -S nmin option will substitute the
positional parameters - up to at least nmin - but will not
push nor set environment
variables. execlineb -S3 -c "script" is equivalent to,
but more efficient than, execlineb -c "elgetpositionals -P3 emptyenv
-P script". See
the details.
- The -s nmin option behaves just like the
-S option, except that it defines $@ as the rest of the
command line after nmin arguments have been
removed.
Current limitations
execlineb builds and executes a unique
argv with the script: hence scripts are subject to OS-dependent
limitations such as the kernel buffer size for argv and envp
- at least 64 kB on most systems. This means that execlineb cannot
execute arbitrarily large scripts. Be careful with deeply nested scripts too:
without the -p/-P/-S/-s option, each
execlineb invocation uses up some space in the environment.