5

2 つのプロセスをパイプし、パイプの「出力」で 1 つを強制終了すると、最初のプロセスが「Broken Pipe」シグナルを受信するために使用され、通常はそれも終了していました。例:ランニング

$> do_something_intensive | less

SuSE8またはそれ以前のリリースでは、すぐにレスポンシブ シェルに戻ります今日それを試しているとき、手動で強制終了するまで、do_something_tensiveは明らかにまだ実行されています。プログラムが「壊れたパイプ」を無視するようにする何かが変更されたようです(glib?シェル?)...

あなたの誰かがこれについてのヒントを持っていますか? 以前の動作を復元する方法は? なぜ変更されたのですか (または、常に複数のセマンティクスが存在するのはなぜですか) ?

edit : さらにテスト (strace を使用) すると、「SIGPIPE」生成されていることがわかりますが、プログラムは中断されていません。シンプルな

#include <stdio.h>
int main() 
{
   while(1) printf("dumb test\n");
   exit(0);
}

エンドレスに続きます

--- SIGPIPE (Broken pipe) @ 0 (0) ---
write(1, "dumb test\ndumb test\ndumb test\ndu"..., 1024) = -1 EPIPE (Broken pipe)

レスが殺されたとき。プログラムでシグナルハンドラをプログラムして確実に終了させることはできますが、SIGPIPEでプログラムを強制的に終了させる環境変数またはシェルオプションをもっと探しています

もう一度編集: tcsh 固有の問題 (bash が適切に処理) と端末依存 (Eterm 0.9.4) のようです。

4

3 に答える 3

8

リーダーがなくなった後にパイプに書き込もうとすると、SIGPIPE シグナルが生成されます。アプリケーションにはこのシグナルをキャッチする機能がありますが、キャッチできない場合、プロセスは強制終了されます。

SIGPIPE は、呼び出しプロセスが書き込みを試みるまで生成されないため、出力がなくなると生成されません。

于 2008-09-19T15:45:12.820 に答える
2

「集中的に何かをする」ことはまったく変わりましたか?

ダニエルが述べたように、SIGPIPE は魔法の「パイプが消えた」シグナルではなく、「良い試みです。そのパイプを読み書きすることはできなくなりました」シグナルです。

「集中的に何かを行う」ことを制御できる場合は、回転中に「進行状況インジケーター」出力を書き出すように変更できます。これにより、タイムリーに SIGPIPE が発生します。

于 2008-09-19T16:26:02.393 に答える
0

アドバイスをありがとう、解決策は近づいています...

tcsh のマンページによると、「非ログイン シェルは親から終了動作を継承します。他のシグナルは、シェルが親から継承した値を持ちます。」

私の端末が実際に問題の根源であることを示唆しています... SIGPIPEを無視した場合、シェル自体もSIGPIPEを無視します...

編集:問題がEterm + tcshでのみ発生し、Etermソースコードに疑わしいシグナル(SIGPIPE、SIG_DFL)が見つからないという決定的な確認があります。私はケースを閉じると思います。

于 2008-09-23T15:50:35.503 に答える