Puoi usare env per vedere tutte le variabili di ambiente attualmente definite e quindi utilizzare quell'elenco per sostituirle solo. (La pagina man non è molto chiara su questo, ma vedi questa risposta per chiarimenti.)
echo 'Hello $USER $UNKNOWN' | envsubst "$(env | cut -d= -f1 | sed -e 's/^/$/')"
(L'output di env elenca anche i valori delle variabili, ma envsubst vuole anche vedere un $ in testa , quindi non possiamo semplicemente usare cut -d= -f1 da solo, purtroppo. Potresti usare un singolo sed fare cut anche il lavoro di , vedere la revisione precedente, ma preferisco la chiarezza di cut rispetto a un piccolo guadagno in termini di prestazioni.)
Se passi un argomento come $USER$PATH a envsubst , quindi espande solo quelle variabili a cui si fa riferimento in quell'argomento.
Quindi un modo potrebbe essere quello di passargli tutte le variabili di ambiente attualmente definite in quel formato. Con zsh :
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst \$${(kj:$:)parameters[(R)*export*]}
$parametersè uno speciale array associativo che associa i nomi delle variabili al loro tipo$parameters[(R)*export*]si espande a tutti gli elementi dell'array associativo il cui valore contieneexport.- con il
kflag di espansione del parametro, la chiave invece del valore viene restituito j:$:unisce questi elementi con$in mezzo, e ne aggiungiamo uno all'inizio.
Con altre shell, puoi sempre tornare a perl per ottenere quell'elenco:
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"
Fai attenzione a non rivelare la tua variabile d'ambiente nomi nell'output di ps .
Invece, potresti anche fare tutto in perl :
perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'
Attenzione, ha le stesse limitazioni come envsubst in quanto non espanderà cose come ${VAR:-x} e espanderebbe $HOME in cose come \$HOME o $$HOME cosa che una shell non farebbe.