名前付きパイプへの送信時にプロセスが予期せず終了する

名前付きパイプへの送信時にプロセスが予期せず終了する

プロセスが 2 つと名前付きパイプが 1 つあります。

1 つのプロセスがパイプからアクティブに読み取り、もう 1 つのプロセスがパイプに継続的にデータを送信しています。

パイプに送信するコマンドは次のとおりです。

sudo iotop -b -P > diskfifo

一方、リーダーはパイプ上でループ読み取り操作を実行するだけです。

pipe=./diskfifo

while read line <$pipe
do
    if [[ "$line" == 'quit' ]]; then
        break
    fi
    echo $line
done

問題: iotop コマンドは、一定回数実行した後に停止することがあり、その理由がわかりません。

しかし、送信されるデータの量を減らすと、iotop コマンドが停止しないことに気付きました。

答え1

ループの各反復で、read読み取り用にパイプを開き、データの行を読み取ってから閉じます。

iotopパイプからアクティブに読み取りを行っていないときにパイプに書き込もうとするとread、誰も読み取りを行っていないパイプに書き込もうとするため、シグナルを受信しますPIPE。シグナルを受信したときのデフォルトのアクションは、PIPEプロセスを終了することです。

ループ内での読み取りのためにパイプを開いたり閉じたりする代わりに (そして、iotop読み取られていない間にパイプに書き込まれないことを期待する代わりに)、パイプからの入力をループ自体にリダイレクトします。

pipe=./diskfifo

while read word; do
    [ "$word" = 'quit' ] && break
    printf '%s\n' "$word"
done <"$pipe"

これにより、ループの全期間にわたってパイプが開いたままになります。 の各呼び出しは、readパイプに接続されているループの標準入力から標準入力ストリームを継承します。


ループの別の表現例:

while read word && [ "$word" != 'quit' ]; do
    printf '%s\n' "$word"
done <"$pipe"

関連情報