Vous pouvez utiliser env
pour voir toutes les variables d'environnement actuellement définies, puis utilisez cette liste pour ne remplacer que celles-ci. (La page de manuel n'est pas très claire à ce sujet, mais consultez cette réponse pour plus d'explications.)
echo 'Hello $USER $UNKNOWN' | envsubst "$(env | cut -d= -f1 | sed -e 's/^/$/')"
(La sortie de env
répertorie également les valeurs des variables, mais envsubst
veut également voir un $
en tête , nous ne pouvons donc pas simplement utiliser cut -d= -f1
tout seul, malheureusement. Vous pouvez utiliser un seul sed
faire cut
aussi, voir révision précédente, mais je préfère la clarté de cut
sur un petit gain de performances.)
Si vous passez un argument comme $USER$PATH
à envsubst
, il ne développe que les variables référencées dans cet argument.
Donc, une façon pourrait être de lui transmettre toutes les variables d'environnement actuellement définies dans ce format. Avec zsh
:
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst \$${(kj:$:)parameters[(R)*export*]}
$parameters
est un tableau associatif spécial qui associe les noms de variables à leur type$parameters[(R)*export*]
se développe à tous les éléments du tableau associatif dont la valeur contientexport
.- avec le
k
indicateur d'extension de paramètre, la clé au lieu de la valeur est renvoyée j:$:
joint ces éléments avec$
entre les deux, et nous en ajoutons un au début.
Avec d'autres shells, vous pouvez toujours revenir à perl
pour obtenir cette liste :
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"
Méfiez-vous des deux, divulguez vos noms de variable d'environnement dans la sortie de ps
.
Au lieu de cela, vous pouvez également tout faire en perl
:
perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'
Attention, il a les mêmes limitations comme envsubst
en ce sens qu'il ne développera pas des choses comme ${VAR:-x}
et développerait $HOME
dans des choses comme \$HOME
ou $$HOME
ce qu'un obus ne ferait pas.