envsubst: command not found on Mac OS X 10.8

BashShellTerminalShCommand Line-Interface

Bash Problem Overview


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.

Bash Solutions


Solution 1 - Bash

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.

Solution 2 - Bash

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: https://stackoverflow.com/questions/14940383/how-to-install-gettext-on-macos-x

Solution 3 - Bash

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)
  • Commands directly built into 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 builtin
  • envsubst 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
  • whereas eval will expand shell variable references too - as well as embedded command substitutions, which is what makes use of eval a security concern.

Solution 4 - Bash

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

Solution 5 - Bash

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;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrewView Question on Stackoverflow
Solution 1 - BashcobberboyView Answer on Stackoverflow
Solution 2 - BashymonadView Answer on Stackoverflow
Solution 3 - Bashmklement0View Answer on Stackoverflow
Solution 4 - BashiRaSView Answer on Stackoverflow
Solution 5 - BashcyberzView Answer on Stackoverflow