
私はこの質問を偶然見つけました。特定の変数のみをenvsubstに置き換えるそしてそのうちの一つでコメントこのシェルの例は次のとおりです。
envsubst "$(printf '${%s} ' ${!PREFIX*})" < infile
完全な背景に関する元の質問を参照してください。ただし、基本的にenvsubstは、文字列「PREFIX」で始まる環境変数のみを置き換えるように指示します。
しかし、これはどのように機能しますか?誰かが関連するさまざまな「ステップ」を説明できますか? infileを最初に読みますか?ファイルの入力を有効にするためにgrep / findのようなことをする部分は何ですか?パラメータ "${!PREFIX*}" は一種の正規表現ですか?ここでサブシェル魔法が起こっていますか?
よりよく理解するために、次の内容で独自のinfileを作成しました。
1: ${VAR1}
2: ${VAR2}
3: ${VAR3}
4: ${PREFIX_1}
5: ${PREFIX_2}
6: ${PREFIX_3} ?
7: ${PREFIX_4} + ${PREFIX_5}
8: ${VAR4}
9: bla bla bla
その後、envsubstをechoに変更し、結果は次のようになります。
echo "$(printf '${%s} ' ${!PREFIX*})" < infile
この結果は次のとおりです。
${PREFIX_1}
したがって、動作しますが、最初のゲームにのみ適用されます。私は何が間違っていましたか?出力には、すべての「PREFIX_」変数1〜5が含まれると予想されます。 envsubstをechoに置き換えたときに私はめちゃくちゃになりましたか?それでは、envsubstに送信される内容をどのように確認できますか?
答え1
${!prefix_*}
で始まるすべてのシェル変数の名前に拡張されるBash機能ですprefix_
。次に、コマンドの代替をprintf
中かっこで印刷します(必要に応じてフォーマット文字列を繰り返します)。
$ prefix_foo=1 prefix_bar=2
$ printf '${%s}\n' ${!prefix_*}
${prefix_bar}
${prefix_foo}
コマンドの置き換えのため、envsubst
コマンドラインから削除されます。拡張およびコマンド置換の結果には単語の区切りが含まれますが、変数名にはスペースやワイルドカードを含めることはできないため、これはデフォルトとは無関係です。${!prefix_*}
IFS
echo "$(printf '${%s} ' ${!PREFIX*})" < infile
ここでは標準入力から何も読み取らないので、内容はinfile
重要ではありません。echo
で始まる変数名のみが印刷されますPREFIX
。