別のコマンドにパイプしたり、ファイルにリダイレクトしたりするスクリプトがあるとします(例では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
別の、私の意見ではより良い構文です:
(
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を実行するように言っています。つまり、fd 3からの入力を除外します。(...)
が開始される前に、シェルは2つのhereドキュメントのリダイレクトを確認し、fd 0(<<EOF
)とfd 3(3<<EOF2
)をパイプの読み取り側に置き換えますmeow
の使用はEOF
と同じくらい有効であることを指摘したいだけです。
このスクリプトは、cat
という名前のファイルにMeow!
を追加します。
#!/bin/sh
cat <<meow>> cat
Meow!
meow
cats
として保存し、chmod +x cats
で実行可能にしてから、./cats
で実行します。
$ ./cats
$ cat cat
Meow!
$ ./cats
$ cat cat
Meow!
Meow!
説明:
cat <<meow
はhere document構文です。文字列meow
が見つかるまで、この行に続くテキストブロックを取得するようにスクリプトに指示します。次に、コンテンツが出力(またはパイプ)されます。>> cat
は、cat
という名前のファイルにパイプします。>
の代わりに>>
を使用すると、ファイルに追加するのではなく、ファイルを上書きします。Meow!
は、こちらのドキュメントの内容です。meow
は、hereドキュメントの終了マーカーです。内容は、>>
を使用して、cat
に追加されます。stdoutとファイルの両方にパイプする:
リクエストしたパイピングを行うために、ヒアドキュメントは必要ありません。
cat
はテキストを出力することもテキストを渡すこともできませんが、tee
はあなたが求めているものと完全に一致します。
echo echo | tee tee
これにより、文字列echo
が出力され、echo
がtee
という名前のファイルに書き込まれます。
cat
を介して出力を渡すこともできます。これが要件の一部である場合は、次のいずれかを使用します。
echo echo | tee tee | cat </dev/stdin
あるいは単に:
echo echo | tee tee | cat
ファイルの内容:
$ cat tee
echo