これを行う明白な方法には、多くの問題があります。
# これは特定の入力で失敗します。HTMLは確かに問題になります
# '<' および '>' 文字はファイル リダイレクトとして解釈されるため
$ 読み取り中 r; do eval echo $r; 完了 < 入力
次の perl は、単純な入力の問題をかなりうまく処理するはずです。
$ perl -pwe 'while(($k,$v) = each %ENV ) { s/\${?$k}?/$v/ }' 入力
しかし、${FOO-bar} のような構造では何もしません。このような構成を処理する必要がある場合は、すべてのシェル メタ文字をエスケープし、while/read ループを実行するだけで十分な場合があります。
$ sed -e 's/\([<>&|();]\)/\\\1/g' 入力 | 読み取り中 -rl; do eval echo "$l"; 終わり
これは堅牢でも安全でもないことに注意してください。次のような入力で何が起こるかを考えてみましょう:
\; rm -rf /
「検討します」と言いました。それをテストしないでください。sed はセミコロンの前にバックスラッシュを挿入し、eval は文字列 "\\;" を取得します。これは、単一のバックスラッシュとそれに続くエコーを終了するセミコロンとして解釈され、rm -rf が実行されます。未知の入力を評価することの不安を考えると、perl のようなものに固執し、目的の sh 構造を明示的に置き換える方がおそらく安全でしょう。何かのようなもの:
$ perl -pwe 'while(($k,$v) = each %ENV ) { s/\${?$k}?/$v/ };
s/\${[^-]*-([^}]*)}/$1/g' 入力
これは ${FOO=some-text} のような入力に問題があります。sh コンストラクト (${word:rhs} のすべてを確実に取得するには、「:」は「-」、「?」、「=」、「+」、「%」、「#」またはコロンを前に付けた同じもの (または、非 posix sh 構文を許可する場合は他の多くのシンボル!)) を使用すると、かなり複雑な比較セットを作成する必要があります。