When I try to run a script that contains the envsubst command, I get this error. Looking online, this seems to be a standard bash command, so I am not sure what to install in order to get it to work.
brew install gettext
brew link --force gettext
This will enable envsubst on OS X, and force it to link properly. It requires homebrew to be installed.
Edit: @cobberboy 's anwer is more correct. upvote him.
brew install gettext
brew link --force gettext
Following is my old answer:
envsubst
is included in gettext
package.
Therefore you may compile it by your own, using standard build tools such as make
or using homebrew
.
However, it seems to have little issue when installing gettext
in MacOS.
See following url for details: How to install gettext on MacOS X
To clear up potential confusion:
envsubst
is an external executable and thus not part of Bash; external executables are platform-dependent, both in terms of which ones are available as well as their specific behavior and the specific options they support (though, hopefully, there is a common subset based on the POSIX specifications)bash
are called builtins, and only they can be relied upon to be present on all platforms.To test whether a given command is a builtin, use
type <cmdName>
In the case at hand, running type envsubst
on macOS 10.13 returns -bash: type: envsubst: not found
, from which you can infer:
envsubst
is NOT a builtinenvsubst
is not in your system's $PATH
(and thus likely not present on your system)(By contrast, running the same on command on, e.g., a Ubuntu 12.04 system returns envsubst is hashed (/usr/bin/envsubst)
, which tells you that the utility is present and where it is located.)
A makeshift alternative to envsubst
is to use eval
, although the usual caveat applies: use eval
only on strings whose content you control or trust:
Assume a sample.txt
file containing text with unexpanded variable references; e.g.:
cat > sample.txt <<'EOF'
Honey, I'm $USER
and I'm $HOME.
EOF
The equivalent of:
envsubst < sample.txt
is:
eval "echo \"$(sed 's/"/\\"/g' sample.txt)\""
There is a crucial difference, however:
envsubst
expands only environment variable references
eval
will expand shell variable references too - as well as embedded command substitutions, which is what makes use of eval
a security concern.
If you don't want to bother installing homebrew and gettext, a one line perl executable will do:
#!/usr/bin/perl -p
$_ =~ s/\Q${$1||$2}/$ENV{$1?$2:$4}/ while $_ =~ /(\$\{([^}]+)})|(\$(\w+))/g;
I'm using this now in my bash script that requires envsubst:
if ! which envsubst > /dev/null 2>&1; then
envsubst() {
while read line; do
line=$( echo $line | sed 's/"/\\"/g' )
eval echo $line
done
}
fi
you can use it as the envsubst command - of course it's not feature complete or something else:
envsubst <<<'Honey, I am $HOME.'
envsubst < input > output 2> corrupt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With