Sie können env
verwenden um alle aktuell definierten Umgebungsvariablen anzuzeigen und diese Liste dann zu verwenden, um nur diese zu ersetzen. (Die Manpage ist diesbezüglich nicht sehr klar, aber siehe diese Antwort zur Erläuterung.)
echo 'Hello $USER $UNKNOWN' | envsubst "$(env | cut -d= -f1 | sed -e 's/^/$/')"
(Die Ausgabe von env
listet auch die Werte der Variablen auf, aber envsubst
möchte auch eine vorangestellte $
sehen , also können wir nicht einfach cut -d= -f1
verwenden leider alleine. Sie könnten einen einzelnen sed
verwenden zu tun cut
auch die Aufgabe von , siehe vorherige Überarbeitung, aber ich bevorzuge die Klarheit von cut
über einen winzigen Leistungsgewinn.)
Übergeben Sie ein Argument wie $USER$PATH
bis envsubst
, dann werden nur die Variablen erweitert, auf die in diesem Argument verwiesen wird.
Eine Möglichkeit könnte also darin bestehen, alle derzeit definierten Umgebungsvariablen in diesem Format zu übergeben. Mit zsh
:
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst \$${(kj:$:)parameters[(R)*export*]}
$parameters
ist ein spezielles assoziatives Array, das Variablennamen ihrem Typ zuordnet$parameters[(R)*export*]
erweitert sich auf alle Elemente des assoziativen Arrays, dessen Wertexport
enthält .- mit dem
k
Parameter-Erweiterungs-Flag, der Schlüssel statt dessen wird der Wert zurückgegeben j:$:
verbindet diese Elemente mit$
dazwischen, und wir fügen einen am Anfang hinzu.
Bei anderen Shells können Sie jederzeit zu perl
zurückkehren um diese Liste zu erhalten:
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"
Achten Sie darauf, dass beide Ihre Umgebungsvariablen Namen offenlegen in der Ausgabe von ps
.
Stattdessen könnte man das Ganze auch in perl
machen :
perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'
Beachten Sie, dass es die gleichen Einschränkungen hat als envsubst
darin, dass Dinge wie ${VAR:-x}
nicht erweitert werden und würde $HOME
erweitern in Sachen wie \$HOME
oder $$HOME
was eine Shell nicht tun würde.