What is SHELL-FORMAT in envsubst?
When I stumbled upon envsubst
I wanted to use it for replacing only specific variables and suspected that the SHELL-FORMAT parameter might be what is wanted but I cannot get it to work.
Unfortunately, the man
and info
pages don't give any usage example and only say
If a SHELL-FORMAT is given, only those environment variables that are referenced in SHELL-FORMAT are substituted
Which does not tell me how to reference them.
Solution 1:
As indicated by the text, you just have to reference (e.g. by $VARNAME
or ${VARNAME}
) the variables as in a usual shell command. However, you have to make sure that the shell does not expand them beforehand.
Here are some examples to illustrate this (assuming export FOO=BAR
):
$ echo '$FOO$FOO2' | envsubst
BAR
As you can see, $FOO2 has been replaced by "" as it was not defined. Now we can restrict that replacement to only $FOO by:
$ echo '$FOO$FOO2' | envsubst '$FOO'
BAR$FOO2
using ""
instead of ''
would lead to substitution before it is wanted:
echo '$FOO$FOO2' | envsubst "$FOO"
$FOO$FOO2
(This amounts to the effective call envsubst "BAR"
which detects no variables so none are replaced.)
As the man
-page said, all variables that are referenced in SHELL-FORMAT
are replaced, so we can even do this:
echo '$FOO$FOO2$FOO3' | envsubst '$FOO some more text ${FOO3}'
BAR$FOO2
As you can see, the SHELL-FORMAT
is quite flexible.
Finally, the parameter --variables
allows you to evaluate which variables are selected for substitution by the SHELL-FORMAT
:
envsubst --variables '$FOO some more text ${FOO3}'
FOO
FOO3
In the premature substitution example from above this would have shown the error:
$ envsubst --variables "$FOO"
(empty string returned)
As stated in the man
-page, envsubst
does not process any stdinput when --variables
is present.
Solution 2:
Here are some examples that helped me understand how to use it properly. It was surprising to me that envsubst only replaces variables mentioned in the parameter.
export FOO_X="value_x"
export FOO_Y="value_y"
export FOO_Z="value_z"
$ echo 'x=$FOO_X y=$FOO_Y z=${FOO_Z}' | envsubst
x=value_x y=value_y z=value_z
$ echo 'x=$FOO_X y=$FOO_Y z=${FOO_Z}' | envsubst '$FOO_X'
x=value_x y=$FOO_Y z=${FOO_Z}
$ echo 'x=$FOO_X y=$FOO_Y z=${FOO_Z}' | envsubst '$FOO_X $FOO_Z'
x=value_x y=$FOO_Y z=value_z
$ echo 'x=${FOO_X} y=${FOO_Y} z=${FOO_Z}' | envsubst '$FOO_Z ${FOO_Y}'
x=${FOO_X} y=value_y z=value_z
$VAR
and ${VAR}
both seem to work btw. Order does not matter.
I did not understand what SHELL-FORMAT meant either, still don't know why it is named like that. But after the above experiments I think I know what it does.
Solution 3:
The verbiage is a bit confusion. To reword the help text more meticulously:
SHELL-FORMAT
is an optional text command line argument containing references to environment variables. To reference an environment variable in the text, prefix the variable name with a$
. For example:Hello $FOO World $BAR
references environment variablesFOO
andBAR
. The rest of the string is ignored. If theSHELL-FORMAT
command line argument is present, then when variable substitution occurs on text received through stdin, it will be limited to variables referenced in theSHELL-FORMAT
command line argument.
So to answer your question explicitly: Prefix the variable name with $
.