execline: block management
Keywords: execline block blocks null argument tilda semicolon el_semicolon

execline
Software
skarnet.org

# Blocks

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. They can be nested.

## argv syntax

execlineb reads and parses the script, and converts it into an argv (a simple Unix command line) with a different syntax for blocks. In an argv, blocks are not delimited by braces; they are made of quoted arguments and terminated by an empty word (""). A quoted argument begins with a space. Nested blocks are represented by arguments being quoted several times, i.e. having several spaces in front of them; an empty word inside a block gets quoted too, i.e. it will be represented as a series of spaces.

Actually, the block-reading commands know nothing about braces; they only understand the "quoted arguments + empty word" 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

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: commands that perform substitution inside a block may produce empty words, 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. (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 every time they find an unquoted argument inside a block. If that variable contains `2` or a bigger integer, commands will print an error message and die on unquoted arguments.
You can use execlineb's `-w` or `-W` switch to set `EXECLINE_STRICT` to `1` or `2`.