envsubst: comando não encontrado no Mac OS X 10.8

92

Quando tento executar um script que contém o comando envsubst, recebo este erro. Olhando online, este parece ser um comando bash padrão, então não tenho certeza do que instalar para fazê-lo funcionar.

Andrew
fonte
2
envsubstestá incluído no gettextpacote. você pode compilar por conta própria. consulte stackoverflow.com/questions/14940383/…
ymonad
Quer adicionar isso como uma resposta para que eu possa aceitá-la?
Andrew
Eu postei como resposta.
ymonad

Respostas:

130

Edit: a resposta de @cobberboy é mais correta. votar a favor dele.

brew install gettext
brew link --force gettext 

A seguir está minha velha resposta:

envsubstestá incluído no gettextpacote.

Portanto, você pode compilá-lo por conta própria, usando ferramentas de construção padrão como makeou usando homebrew.

No entanto, parece ter poucos problemas ao instalar gettextno MacOS. Consulte o seguinte url para obter detalhes: Como instalar gettext no MacOS X

Ymonad
fonte
8
Embora envsubstseja parte do gettext (instalado pelo homebrew), ele não é vinculado por padrão. Espero que isso aconteça porque gettext é uma fórmula exclusiva para barris. Você poderia dizer ao homebrew para ligar o barril, mas isso pode ter efeitos colaterais indesejados. Uma abordagem menos intrusiva é configurar um alias adicionando alias envsubst='/usr/local/Cellar/gettext/0.19.6/bin/envsubst'ao seu .profile(ou equivalente). Claro, você pode ter outra versão do gettext instalada. Você pode aprender sobre isso executando brew info gettext.
trkoch de
1
@trkoch Você provavelmente quer usar o apelido /usr/local/opt/gettext/bin/envsubstque sobrevive a atualizações
Christoph Hösler
1
Embora esta seja a resposta aceita, role para baixo até a resposta de @cobberboy, pois também é comum que você precise forçar o link.
Big Money
Eu me perguntei por que de repente estava recebendo mais votos positivos. Obrigado por sua generosidade @ymonad
cobberboy
1
Vinculando /usr/local/Cellar/gettext/0.19.8.1 ... 194 links simbólicos criados ... wtf 194 links simbólicos?
Alexander Mills
233
brew install gettext
brew link --force gettext 

Isso habilitará o envsubst no OS X e o forçará a vincular corretamente. Requer a instalação do homebrew.

cobberboy
fonte
1
Linking /usr/local/Cellar/gettext/0.19.8.1... 194 symlinks created... links simbólicos wtf 194?
Alexander Mills
@AlexanderMills, sim, gettextinclui um monte de coisas; parece um exagero apenas ser envsubstinstalado, mas é a maneira mais rápida e simples.
cobberboy
parece que eles estão ligando simbolicamente cada arquivo em vez de apenas criar um link simbólico para uma pasta
Alexander Mills
17

Para esclarecer possíveis confusões:

  • envsubsté um executável externo e, portanto, não faz parte do Bash ; executáveis ​​externos são dependentes da plataforma , tanto em termos de quais estão disponíveis quanto em seu comportamento específico e as opções específicas que eles suportam (embora, esperançosamente, haja um subconjunto comum baseado nas especificações POSIX)
  • Comandos diretamente incorporadas bashsão chamados builtins , e só eles podem ser invocadas para estar presente em todas as plataformas .

Para testar se um determinado comando é interno , use

type <cmdName>

No caso em questão, a execução type envsubstno macOS 10.13 retorna -bash: type: envsubst: not found, a partir do qual você pode inferir:

  • envsubst NÃO é embutido
  • envsubstnão está no seu sistema $PATH(e, portanto, provavelmente não está presente no seu sistema)

(Por outro lado, a execução do mesmo comando no, por exemplo, um sistema Ubuntu 12.04 retorna envsubst is hashed (/usr/bin/envsubst), informando que o utilitário está presente e onde está localizado.)


Uma alternativa improvisada envsubsté usar eval, embora a advertência usual se aplique: use evalapenas em strings cujo conteúdo você controla ou confia:

Considere um sample.txtarquivo contendo texto com referências de variáveis ​​não expandidas; por exemplo:

cat > sample.txt <<'EOF'
Honey, I'm $USER
and I'm $HOME.
EOF

O equivalente a:

envsubst < sample.txt

é:

eval "echo \"$(sed 's/"/\\"/g' sample.txt)\""

Há uma diferença crucial , no entanto:

  • envsubstexpande apenas referências de variáveis ​​de ambiente
  • enquanto que evalirá expandir as referências de variáveis ​​de shell também - bem como substituições de comandos embutidos , que é o que faz uso de evaluma preocupação de segurança.
mklement0
fonte
Gosto da ideia eval echoporque confio na fonte, mas não é a mesma .. envsubst < .env.examplenão pode ser apenaseval echo < .env.example
iRaS
1

Estou usando isso agora em meu script bash que requer 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

você pode usá-lo como o comando envsubst - é claro que não é um recurso completo ou outra coisa:

envsubst <<<'Honey, I am $HOME.'
envsubst < input > output 2> corrupt
iRaS
fonte
Isso parece remover todos os espaços em branco à esquerda e à direita
sudo
como disse, esta é uma solução alternativa que não está completa. você poderia tentar adicionar "cerca de $ linha, mas eu não tentei ainda
iRaS
0

Se você não quiser se preocupar em instalar homebrew e gettext, um executável perl de uma linha servirá:

#!/usr/bin/perl -p
$_ =~ s/\Q${$1||$2}/$ENV{$1?$2:$4}/ while $_ =~ /(\$\{([^}]+)})|(\$(\w+))/g;
cyberz
fonte