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*]}
$parametersest 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
kindicateur 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.