別のコマンドにパイプしたり、ファイルにリダイレクトしたりするスクリプトがあるとします(sh
にパイプします)。 例について)。私がbashを使用していると仮定します。
echo
を使用してそれを行うことができます :
echo "touch somefile
echo foo > somefile" | sh
cat
を使用してもほぼ同じことができます :
cat << EOF
touch somefile
echo foo > somefile
EOF
しかし、「EOF」を「EOF | sh」それはヒアドキュメントの一部であると考えているだけです。
cat
になるようにするにはどうすればよいですか? stdinからテキストを出力し、それを任意の場所にパイプしますか?
承認された回答:
これを行うには複数の方法があります。最も単純なのはおそらくこれです:
cat <<EOF | sh
touch somefile
echo foo > somefile
EOF
もう1つ、私の意見ではより良い構文です:
(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh
これも同様に機能しますが、サブシェルはありません:
{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh
その他のバリエーション:
cat <<EOF |
touch somefile
echo foo > somefile
EOF
sh
または:
{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF
ちなみに、cat
の使用を期待しています あなたの質問では、他の何かのプレースホルダーです。そうでない場合は、次のように取り出します:
sh <<EOF
touch somefile
echo foo > somefile
EOF
これはこれに簡略化できます:
sh -c 'touch somefile; echo foo > somefile'
または:
sh -c 'touch somefile
echo foo > somefile'
配管の代わりに出力をリダイレクトする
sh >out <<EOF
touch somefile
echo foo > somefile
EOF
cat
を使用する echo test > out
に相当するものを取得するには :
cat >out <<EOF
test
EOF
複数のヒアドキュメント
( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2
これにより、出力が生成されます:
hi
---
there
何が起こっているのか:
- シェルは
( ... )
を認識します 囲まれたコマンドをサブシェルで実行します。 - 猫とエコーは十分に単純です。
cat <&3
fd 3からリダイレクトされたファイル記述子(fd)0(stdin)でcatを実行するように言います。つまり、fd3からの入力を削除します。 -
( ... )
の前 が開始されると、シェルはヒアドキュメントの2つのリダイレクトを確認し、fd 0(<<EOF
)およびfd 3(3<<EOF2
)パイプの読み取り側を使用 - 最初のコマンドが開始されると、シェルはEOFに到達するまでそのstdinを読み取り、それを最初のパイプの書き込み側に送信します
- 次に、EOF2と2番目のパイプの書き込み側でも同じことを行います