What is SHELL-FORMAT in envsubst?

20

4

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.

Nobody

Posted 2016-11-23T11:54:53.223

Reputation: 685

Answers

21

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.

Nobody

Posted 2016-11-23T11:54:53.223

Reputation: 685

8

Here are some examples that helped me understand how to use it properly. It was surprising to me that envsubstonly replaces variables mentioned in the parameter.

$ export FOOX="foox"
$ export FOOY="fooy"
$ export FOOZ="fooz"

$ echo 'x $FOOX y $FOOY z $FOOZ' | envsubst            
x foox y fooy z fooz

$ echo 'x $FOOX y $FOOY z $FOOZ' | envsubst '$FOOX'
x foox y $FOOY z $FOOZ

$ echo 'x $FOOX y $FOOY z $FOOZ' | envsubst '$FOOX $FOOZ'
x foox y $FOOY z fooz

$ echo 'x $FOOX y $FOOY z $FOOZ' | envsubst '$FOOZ $FOOY'
x $FOOX y fooy z fooz

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.

dedeibel

Posted 2016-11-23T11:54:53.223

Reputation: 210

This help me a lot after read those example, from man help and info, only know SHELL-FORMAT exist, but don't know how to declare it! – zw963 – 2018-09-21T15:12:00.780

1

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 variables FOO and BAR. The rest of the string is ignored. If the SHELL-FORMAT command line argument is present, then when variable substitution occurs on text received through stdin, it will be limited to variables referenced in the SHELL-FORMAT command line argument.

So to answer your question explicitly: Prefix the variable name with $.

wizulus

Posted 2016-11-23T11:54:53.223

Reputation: 111