web-dev-qa-db-ja.com

catSTDINはスクリプトで2回機能しません

さまざまな情報とhtmlフォームのテキストフィールドを出力するスクリプトがあります(メソッドPOST)。 cat <&0を実行しようとすると、正しく表示されます。しかし、数行下に、もう一度<&0をcatしようとすると、何も出力されません。私は何が間違っているのですか?

....
cat <&0
echo Content length is $CONTENT_LENGTH
cat <&0 | sed -e 's/&/\n/g' | cut -d'=' -f2

....
2
swam

あなたは何も悪いことをしていません:これは私たちが期待すべきことです。

最初のcat <&0は、標準入力の内容全体を消費します。これは、catが行うことであり、最後まですべての入力を読み取ります。

2番目のcat <&0が実行されると、標準入力で消費するものは何も残っていません。ファイルの終わりはすでに以前に到達しています。

シェルスクリプトで、標準入力を2回以上通過させる必要がある場合は、それを一時ファイルにダンプしてから、必要な回数だけ一時ファイルを処理する必要があります。

/tmpで一時ファイルを安全に作成し、スクリプトが終了または終了したときにそれらが正しく破棄されることを確認することは、演習として残されています:-)

ちなみに、<&0は不要で、何もしません。その機能は、標準入力をファイル記述子0 ...にポイントすることです。これは、標準入力です...定義上、標準入力はすでにポイントしています。代わりに、そのコマンドをcatだけにすることができます。

8
Celada

標準入力から2回読み取りたい場合は、何らかの方法で(おそらく、一時ファイルに)バッファリングする必要があります。最初のcatteeの呼び出しに置き換えることができ、ファイルにデータを書き込みます。これはcatの2番目の呼び出しで再読み取りできます(これは不要です)。いずれか; sedはファイルから直接読み取ることができます)。

tee > input_buffer  # Copy standard input to a file and standard output
echo Content length is $CONTENT_LENGTH
sed -e 's/&/\n/g' input_buffer | cut -d = -f2 
5
chepner