6

私は、perlipcのドキュメントにあるものを調べようとしています。

パイプに書き込んでいる場合は、SIGPIPE もトラップする必要があります。それ以外の場合は、存在しないコマンドへのパイプを開始したときに何が起こるかを考えてみてください: open() はおそらく成功します (fork() の成功を反映するだけです) が、出力は失敗します- -壮観に。Perl は、コマンドが実際には exec() が失敗した可能性のある別のプロセスで実行されているため、コマンドが機能したかどうかを知ることができません。したがって、偽のコマンドのリーダーはファイルの終わりをすばやく返すだけですが、偽のコマンドのライターは、処理する準備をしたほうがよいシグナルをトリガーします。検討:

   open(FH, "|bogus")  or die "can't fork: $!";
   print FH "bang\n"   or die "can't write: $!";
   close FH            or die "can't close: $!";

それは終わりまで爆発せず、SIGPIPE で爆発します。それをキャッチするには、これを使用できます:

   $SIG{PIPE} = 'IGNORE';
   open(FH, "|bogus")  or die "can't fork: $!";
   print FH "bang\n"   or die "can't write: $!";
   close FH            or die "can't close: status=$?";

私がそれを正しく読んでいる場合、最初のバージョンは最終的なクローズまでおそらく死なないだろう.

しかし、それは私の OS X ボックス (Perl バージョン 5.8.9 から 5.15.9) では起こりません。openそこに $SIG{PIPE} 行があるかどうかに関係なく、「フォークできません: そのようなファイルまたはディレクトリはありません」で爆発します。

私は何を誤解していますか?

4

2 に答える 2

3

これは、5.6の開発中に実装された変更であり、system()が子のフォーク/実行に失敗したことを検出できるようになりました。

https://github.com/mirrors/perl/commit/d5a9bfb0fc8643b1208bad4f15e3c88ef46b4160

http://search.cpan.org/dist/perl/pod/perlopentut.pod#Pipe_Opensにも記載されています

それ自体がperlipcを指していますが、perlipcにはこれが欠けているようです

于 2012-05-05T00:56:25.793 に答える
0

Perl、v5.14.2Ubuntu 12.04 での同じ出力:

$ perl
   open(FH, "|bogus")  or die "can't fork: $!";
   print FH "bang\n"   or die "can't write: $!";
   close FH            or die "can't close: $!";
can't fork: No such file or directory at - line 1.

そして、そのエラーは奇妙です。フォークとは何の関係もないからです。実行できるかどうかを確認するために、先読み推測を追加したに違いありませんbogus。(これはせいぜい競合状態ですが、一般的なケースでは大幅に優れたエラー処理を提供する可能性が高く、競合が失われたときの古い動作と同じくらい不便です。)

于 2012-05-04T22:33:57.687 に答える