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*]}
$parameterses 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
kindicador 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.