ヒアドキュメントをテンプレートとして使用して、いくつかのコンテンツを生成したいと思います。
passphrase=$(<passphrase) envsubst <<EOF
apiVersion: v1
kind: Secret
metadata:
name: openshift-passphrase
stringData:
passphrase: ${passphrase}
EOF
oc create -f -
にパイプします。
EOF
の後にパイプを追加すると、機能しません。
変数置換を使用してヒアドキュメントをそれを消費するものにパイプするにはどうすればよいですか?
まず、_<<
_の直後にEOF
の任意の部分を引用する必要があります。最も自然な方法は_<<"EOF"
_ですが、_<<E"OF"
_または_<<""EOF
_でもかまいません。これがないと、envsubst
は_${passphrase}
_がすでに展開されている文字列を取得します。 envsubst
はリテラル_$foo
_または_${foo}
_サブストリングを持つ文字列を操作するため、事前にそれらを展開すると、envsubst
は何の関係もありません。さらに、あなたの場合、コード内の変数定義はシェル自体ではなくenvsubst
にのみ影響するため、シェルはおそらく_${passphrase}
_を空の文字列に展開します。同じ名前の変数が(誤って?)事前にシェルに設定されていない限り。
今、私たちはあなたの明確な質問に行き着きます。結果を任意のコマンドにパイプすることができますが、それでも最後のEOFを別の行に保持する必要があります。これを行う1つの方法は、次のとおりです。
_passphrase=$(<passphrase) envsubst <<"EOF" | oc create -f -
apiVersion: v1
kind: Secret
metadata:
name: openshift-passphrase
stringData:
passphrase: ${passphrase}
EOF
_
または、サブシェルにあるコードを実行することもできます。
_( passphrase=$(<passphrase) envsubst <<"EOF"
apiVersion: v1
kind: Secret
metadata:
name: openshift-passphrase
stringData:
passphrase: ${passphrase}
EOF
) | oc create -f -
_
パイプラインの各コマンドは、独自のサブシェルで実行されます
したがって、最初のソリューションでも、_( )
_なしでパイプを構築できた場合、その最初の部分(_|
_の前)はとにかくサブシェルで実行されます。 2番目の解決策は、このサブシェルを明示的にします。明示的な_(
_を使用した後、シェルは明示的な_)
_を待機します。これにより、終了EOF
の後に何かを配置できます。
驚くべきことに、最初のソリューションでも、単一の複合コマンドで複数のヒアドキュメント(_<<
_)を使用できます。このようなリダイレクトはパイプではほとんど意味がありませんが、_&&
_および_||
_で役立つ場合があります。
_command1 <<EOF && command2 <<EOF || command3 <<EOF
content1
EOF
content2
EOF
content3
EOF
_
明示的なサブシェルを使用して、同じように再配置しました。
_( command1 <<EOF
content1
EOF
) && ( command2 <<EOF
content2
EOF
) || command3 <<EOF
content3
EOF
_
状況によっては、一方の表記をもう一方の表記よりも優先する場合があります。
特定の例に戻ります。サブシェルを使用すると、envsubst
も必要ありません。
_( passphrase=$(<passphrase); oc create -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: openshift-passphrase
stringData:
passphrase: ${passphrase}
EOF
)
_
この方法と前の2つの方法には興味深い違いがあります。
${passphrase}
_を展開する必要があるため、_<<EOF
_ではなく_<<"EOF"
_になります。oc
だけでなく、サブシェルにも認識されている必要があります。これは、… passphrase=$(<passphrase) oc create -f - <<…
(セミコロンがないことに注意)が機能しないことを意味します。( )
_がない)同じコードも機能しますが、変数はメインシェルに残ります。サブシェルでコードを実行すると、変数はそれとともに消滅します。元のコードでは、変数はメインシェルに設定されていないので、これが必要なものだと思います。