Bashでprintfコマンドの内部動作を説明できますか?

Bashでprintfコマンドの内部動作を説明できますか?

私はこの質問を偶然見つけました。特定の変数のみを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

おすすめ記事