execline
Software
www.skarnet.org
Blocks
You can read
the discussion that led to the current block implementation.
A command line (and thus an execline script) is one-dimensional. But a
Unix execution flow can be two-dimensional: when two
instructions are sequenced, for instance. In that case, we need a
way to extract two command lines from one argv.
That is precisely what blocks are made for.
execline commands that need more than one linear set of arguments
use blocks. For instance, the
foreground command needs to spawn a
first process, then execute into a second one. It reads the command
line for the first process from a block, and the command line for the
second process from the rest of the argv. In the following script:
#!/command/execlineb
foreground { echo 1 } echo 2
echo 1 is read from a block and spawned; then
echo 2 is executed.
execlineb syntax
In execlineb scripts, blocks are
delimited by braces - nothing more. They can be nested.
argv syntax
The story is quite different in an argv - or in an
execline script, that gets literally
translated into an argv. Blocks are not delimited by braces.
They are made of quoted arguments and terminated by a
single semicolon. A quoted argument begins with a tilda
(~). Nested blocks are represented by arguments being
quoted several times; a semicolon terminator inside a block
gets quoted too.
Actually, the block-reading commands know nothing about braces;
they only understand the "quoted arguments + semicolon" syntax.
So if you want to use foreground
from your shell to sequence echo 1 and
echo 2, you will have to write
$ foreground ~echo ~1 \; echo 2
(since the semicolon is a shell reserved word, it needs to be
escaped by a backslash).
You do not really need to quote every argument inside a block in
that simple case. The following command works as well:
$ foreground echo 1 \; echo 2
However, this is bad practice, because it leads to a security hole
(the same as in execline-0.x): commands that perform
substitution inside a block may
produce bare semicolons, which may modify your script's execution flow.
$ define FOO ';' foreground ~echo '~${FOO}' ~rm ~-rf ~/ \; echo blah
is safe, whereas
$ define FOO ';' foreground echo '${FOO}' rm -rf / \; echo blah
has very much unwanted results. (Kids, don't try this at home.)
You can use the EXECLINE_STRICT environment variable to
check proper block quoting. If that variable contains 1,
commands that read blocks will print a warning message everytime
they find an unquoted argument inside a block. If that variable
contains 2 or more, the command will die instantly.
You can use execlineb's or
execline's -w or -W
switch to set EXECLINE_STRICT to 1 or 2.