bashスクリプトで行をパイプ処理しましたが、プログラムにフィードする前に、パイプにデータがあるかどうかを確認したいと思います。
test -t 0
について見つけた検索 ここでは機能しません。常にfalseを返します。
では、パイプにデータがあることを確認するにはどうすればよいですか?
例:
echo "string" | [ -t 0 ] && echo "empty" || echo "fill"
出力:fill
echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"
出力:fill
前述のパイプラインが出力を生成したかどうかをテストする標準/標準的な方法とは異なりますか?入力をプログラムに渡すには、入力を保持する必要があります。これは、あるプロセスから別のプロセスに出力をパイプする方法を一般化しますが、最初のプロセスに出力がある場合にのみ実行しますか?メールの送信に重点を置いています。
承認された回答:
一般的に利用可能なシェルユーティリティを使用してパイプの内容を確認する方法も、パイプから文字を読み取って元に戻す方法もありません。パイプにデータがあることを知る唯一の方法は、バイトを読み取ることです。次に、そのバイトを宛先に到達させる必要があります。
つまり、次のようにします。1バイトを読み取ります。ファイルの終わりを検出した場合は、入力が空のときに実行したいことを実行します。バイトを読み取った場合は、入力が空でないときに実行したいことをフォークし、そのバイトをそのバイトにパイプし、残りのデータをパイプします。
first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n | tr -dc 0-9)
if [ -z "$first_byte" ]; then
# stuff to do if the input is empty
else
{
printf "\$first_byte"
cat
} | {
# stuff to do if the input is not empty
}
fi
ifne
Joey Hessのmoreutilsのユーティリティは、入力が空でない場合にコマンドを実行します。通常、デフォルトではインストールされませんが、ほとんどのUNIXバリアントで利用可能であるか、簡単に構築できるはずです。入力が空の場合、ifne
何もせず、ステータス0を返します。これは、正常に実行されているコマンドと区別できません。入力が空の場合に何かを実行したい場合は、コマンドが0を返さないように調整する必要があります。これは、成功の場合に識別可能なエラーステータスを返すようにすることで実行できます。
ifne sh -c 'do_stuff_with_input && exit 255'
case $? in
0) echo empty;;
255) echo success;;
*) echo failure;;
esac
test -t 0
これとは何の関係もありません。標準入力が端子かどうかをテストします。入力が利用可能かどうかについては、どちらの方法でも何も述べていません。