Previous: m4 environment, Up: Docker Entrypoint [Contents][Index]
Another way to expand environment variables in the configuration file
is to use xenv
. xenv
is a specialized
preprocessor that expands environment variables in its input. It is
also able to conditionally include parts of text depending on whether
the environment variable is defined. The program is described in
https://www.gnu.org.ua/software/xenv/.
To use xenv
as preprocessor, start pies
as
follows:
pies --foreground --stderr --preprocessor="xenv -s"
The -s option instructs xenv
to emit
synchronization lines, that inform pies
about actual
location of configuration statements in case when the expansion adds
or removes portions of text spanning several lines.
You can also combine the functionality of m4
and
xenv
by running
pies --foreground --stderr --preprocessor="xenv -s -m"
In this case xenv
will automatically feed its output to the
standard input of m4
, started for this purpose.
By default, xenv
uses the shell syntax to expand the
variables. For example, in the following configuration file
fragment, ‘$WORKDIR’ will expand to the actual value of
the WORKDIR
environment variable:
component { chdir "$WORKDIR"; ... }
There are two ways to conditionally include portions of text. The first one is to use the ‘${X:+W}’ construct. For example:
component { ${WORKDIR:+chdir "$WORKDIR";} ... }
Another way is to use the xenv
‘$$ifset’ (or
‘$$ifdef’) statement:
component { $$ifset WORKDIR chdir "$WORKDIR"; $$endif ... }
The difference between ‘$$ifset X’ and ‘$$ifdef X’ is the same as between ‘${X:+W}’ and ‘${X+W}’, i.e. ‘$$ifset’ tests whether the variable is set and not-null, and ‘$$ifdef’ tests only whether it is set, no matter its value.
xenv
extends the shell syntax by providing a ternary
operator. The construct ‘${X|A|B}’ expands to ‘A’ if
the variable X
is set and to ‘B’ otherwise (as usual,
placing the colon before first ‘|’ checks if the variable is set
and not null). This allows for writing compact conditionals:
component syslogd { mode respawn; command "/sbin/syslogd -n ${LOGHOST:|-R $LOGHOST|-O /proc/1/fd/1}"; }
In this example syslogd
is instructed to relay messages to
the IP address specified by the LOGHOST
variable and to send
messages to the container stdout otherwise.
Using shell indirection operator ‘$’ can be confusing in parts of
pies
configuration file that deal with environment variables
by themselves. The common point of confusion is using env
and
command
statements when shell
or expandenv
flag
is set. For example:
component X { env { set "HOME=/var/lib/nobody"; } flags shell; command "marb -C $HOME"; }
Here, the intent is to pass ‘/var/lib/nobody’ as the command line
argument to marb
. However, if pies
was started
with xenv
as preprocessor, the reference ‘$HOME’ will
be expanded by xenv
at the early stage to whatever value the
HOME
variable had at pies
startup. Consequently,
when it comes to launching the ‘X’ component, the intended
expansion won’t take place.
There are three options to handle such cases:
Use backslash to suppress expansion by xenv
:
component X { env { set "HOME=/var/lib/nobody"; } flags shell; command "marb -C \$HOME"; }
This allows to reproduce the desired part of text verbatim. There are two verbatim operators: inline operator ‘$[...]’ and block operator ‘$$verbatim ... $$end’. Examples:
component X { env { set "HOME=/var/lib/nobody"; } flags shell; $[command "marb -C $HOME";] }
or
component X { env { set "HOME=/var/lib/nobody"; } flags shell; $$verbatim command "marb -C $HOME"; $$end }
The indirection operator ‘$’ can be changed either globally, by using the -S option, or locally by using the ‘$$sigil’ statement. E.g.:
$$sigil @ # From this point on, $ looses its special meaning in xenv. component X { env { set "HOME=/var/lib/nobody"; } flags shell; command "marb -C $HOME @FILE"; }
In the command
line of this example, @FILE
will be
expanded by xenv
when processing the configuration file,
and $HOME
will be expanded by shell (to the value
‘/var/lib/nobody’, set by the env
statement) when
pies
will start the command.
Previous: m4 environment, Up: Docker Entrypoint [Contents][Index]