envsubst: comando no encontrado en Mac OS X 10.8

92

Cuando intento ejecutar un script que contiene el comando envsubst, aparece este error. Al buscar en línea, este parece ser un comando bash estándar, por lo que no estoy seguro de qué instalar para que funcione.

Andrés
fuente
2
envsubstestá incluido en el gettextpaquete. puede compilar por su cuenta. ver stackoverflow.com/questions/14940383/…
ymonad
¿Quiere agregar eso como respuesta para que pueda aceptarlo?
Andrew
Lo publiqué como respuesta.
ymonad

Respuestas:

131

Editar: la respuesta de @cobberboy es más correcta. votarlo.

brew install gettext
brew link --force gettext 

A continuación está mi vieja respuesta:

envsubstestá incluido en el gettextpaquete.

Por lo tanto, puede compilarlo por su cuenta, utilizando herramientas de compilación estándar como makeo using homebrew.

Sin embargo, parece tener pocos problemas al instalar gettexten MacOS. Consulte la siguiente URL para obtener más detalles: Cómo instalar gettext en MacOS X

ymonad
fuente
8
Si bien envsubstes parte de gettext (instalado por homebrew), no está vinculado de forma predeterminada. Supongo que esto se debe a que gettext es una fórmula de solo barril. Podría decirle a Homebrew que vincule el barril, pero esto podría tener efectos secundarios no deseados. Un enfoque menos intrusivo es configurar un alias agregando alias envsubst='/usr/local/Cellar/gettext/0.19.6/bin/envsubst'a su .profile(o equivalente). Por supuesto, es posible que tenga instalada otra versión de gettext. Puedes aprenderlo corriendo brew info gettext.
trkoch
2
@trkoch Probablemente quieras usar un alias /usr/local/opt/gettext/bin/envsubstque sobreviva a las actualizaciones
Christoph Hösler
1
Si bien esta es la respuesta aceptada, desplácese hacia abajo hasta la respuesta de @ cobberboy, ya que también es probable que deba forzar el enlace.
Big Money
Me preguntaba por qué de repente recibía más votos a favor. Gracias por tu generosidad @ymonad
cobberboy
1
Vinculando /usr/local/Cellar/gettext/0.19.8.1 ... 194 enlaces simbólicos creados ... wtf 194 enlaces simbólicos?
Alexander Mills
235
brew install gettext
brew link --force gettext 

Esto habilitará envsubst en OS X y lo obligará a vincularse correctamente. Requiere la instalación de homebrew.

cobberboy
fuente
1
Linking /usr/local/Cellar/gettext/0.19.8.1... 194 symlinks created... wtf 194 enlaces simbólicos?
Alexander Mills
@AlexanderMills sí gettextincluye muchísimas cosas; parece exagerado envsubstinstalarlo, pero es la forma más rápida y sencilla.
cobberboy
parece que están vinculando cada archivo en lugar de simplemente vincular una carpeta
Alexander Mills
17

Para aclarar posibles confusiones:

  • envsubstes un ejecutable externo y, por lo tanto, no forma parte de Bash ; Los ejecutables externos dependen de la plataforma , tanto en términos de cuáles están disponibles como de su comportamiento específico y las opciones específicas que admiten (aunque, con suerte, hay un subconjunto común basado en las especificaciones POSIX)
  • Los comandos incorporados directamente bashse denominan incorporados , y solo se puede confiar en que estarán presentes en todas las plataformas .

Para probar si un comando dado es incorporado , use

type <cmdName>

En el caso que nos ocupa, la ejecución type envsubsten macOS 10.13 devuelve -bash: type: envsubst: not found, de la que puede inferir:

  • envsubst NO es un incorporado
  • envsubstno está en el de su sistema $PATH(y, por lo tanto, es probable que no esté presente en su sistema)

(Por el contrario, ejecutar el mismo comando en, por ejemplo, un sistema Ubuntu 12.04 regresa envsubst is hashed (/usr/bin/envsubst), lo que le indica que la utilidad está presente y dónde se encuentra).


Una alternativa improvisada envsubstes usar eval, aunque se aplica la advertencia habitual: use evalsolo en cadenas cuyo contenido controle o en el que confíe:

Suponga un sample.txtarchivo que contiene texto con referencias de variables sin expandir; p.ej:

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

El equivalente de:

envsubst < sample.txt

es:

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

Sin embargo, existe una diferencia crucial :

  • envsubstexpande solo las referencias de variables de entorno
  • mientras que evalse expandirá shell referencias a variables demasiado -, así como embebidos sustituciones de mando , que es lo que hace uso de evalun problema de seguridad.
mklement0
fuente
Me gusta la idea eval echoporque confío en la fuente, pero no es lo mismo ... envsubst < .env.exampleno puede ser simplementeeval echo < .env.example
iRaS
1

Estoy usando esto ahora en mi script bash que requiere 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

puede usarlo como el comando envsubst; por supuesto, no es una característica completa o algo más:

envsubst <<<'Honey, I am $HOME.'
envsubst < input > output 2> corrupt
iRaS
fuente
Esto parece eliminar todos los espacios en blanco iniciales y finales
sudo
como se dijo, esta es una solución que no está completa. podría intentar agregar "alrededor de $ line, pero todavía no probé esto
iRaS
1

Si no quiere molestarse en instalar homebrew y gettext, un ejecutable de perl de una línea servirá:

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