Puedes usar env
para ver todas las variables de entorno definidas actualmente y luego usar esa lista solo para reemplazarlas. (La página de manual no es muy clara al respecto, pero consulte esta respuesta para obtener más información).
echo 'Hello $USER $UNKNOWN' | envsubst "$(env | cut -d= -f1 | sed -e 's/^/$/')"
(La salida de env
enumera los valores de las variables también, pero envsubst
también quiere ver un $
líder , por lo que no podemos simplemente usar cut -d= -f1
solo, por desgracia. Podrías usar un único sed
hacer cut
El trabajo de también, vea la revisión anterior, pero prefiero la claridad de cut
sobre una pequeña ganancia de rendimiento).
Si pasa un argumento como $USER$PATH
a envsubst
, luego expande solo aquellas variables a las que se hace referencia en ese argumento.
Entonces, una forma podría ser pasarle todas las variables de entorno definidas actualmente en ese formato. Con zsh
:
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst \$${(kj:$:)parameters[(R)*export*]}
$parameters
es una matriz asociativa especial que asigna nombres de variables a su tipo$parameters[(R)*export*]
se expande a todos los elementos de la matriz asociativa cuyo valor contieneexport
.- con el
k
indicador de expansión de parámetros, la tecla en lugar del valor se devuelve j:$:
une esos elementos con$
en el medio, y agregamos uno al principio.
Con otros shells, siempre puede volver a perl
para obtener esa lista:
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"
Tenga cuidado al revelar su variable de entorno nombres en la salida de ps
.
En cambio, también podrías hacer todo en perl
:
perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'
Cuidado, tiene las mismas limitaciones como envsubst
en que no expandirá cosas como ${VAR:-x}
y expandiría $HOME
en cosas como \$HOME
o $$HOME
que un caparazón no haría.