2012-02-17 15 views
3

デーモンを書くときに、「良いデーモンの動作」のためにSTDIN、STDOUT、STDERRを閉じたいと思っています。しかし、私は驚いた。 (そのFILENO-sが再オープンしましたので?)ファイルのその後の開口部が古いSTDIN、STDOUTおよびSTDERRと同じ特性を必要とここのperlのバグ?

はwarn.plです:

use warnings; 

my $nrWarnings = 0; 
$SIG{__WARN__} = sub { 
    no warnings; 
    $nrWarnings++; 
    open my $log, '>>', '/tmp/log.txt' 
     or die; 
    printf $log "%d: %s", $nrWarnings, @_; 
    close $log; 
}; 

close STDOUT; 
close STDERR; 
close STDIN; 

open my $o, '>', '/tmp/foobar.txt' 
    or die; 
open my $i, '<', '/etc/passwd' 
    or die; 
open my $i2, '<', '/etc/passwd' 
    or die; 
open my $i3, '<', '/etc/passwd' 
    or die; 

exit $nrWarnings; 

そして、ここで私はそれを実行します:

> rm -f /tmp/log.txt ; perl warn.pl; echo $? ; cat /tmp/log.txt 
3 
1: Filehandle STDIN reopened as $o only for output at warn.pl line 20. 
2: Filehandle STDOUT reopened as $i only for input at warn.pl line 22. 
3: Filehandle STDERR reopened as $i2 only for input at warn.pl line 24. 

私は警告と$を期待していましたか? == 0.バグはどこにありますか?私のコードやperlで?

これはHow can I reinitialize Perl's STDIN/STDOUT/STDERR?と似ているかもしれませんが、私のようにSTDIN、STDOUT、STDERRを閉じるという解決策がありました。

答えて

5

これらは警告であり、エラーではありません。あなたのプログラムがフォークして別のプログラムを実行した場合、そのプログラムは標準入力ストリームが出力用に開かれ、その標準出力とエラーストリームが入力用に開かれるという混乱を招く恐れがあるからです。

あなたが何をしているのかが分かっているときは、警告を表示しないようにするのが正当な方法です。この場合、openの前にno warnings 'io';を追加するだけです。

+0

それは私にとって理にかなっています。 STDINが執筆のためにオープンしているのを見ている子供たちは混乱するでしょう。ありがとう。 –

3

今、提出した直後に、私はperldoc perldiagを見て、そこに警告テキストが記載されていると思います。それは私にPerl bug #23838につながります。これは基本的には:「まあ、それらのハンドルを閉じないで、代わりに「/ dev/null」に再オープンしてください。

そして、そのバグはそれ以降解決されたとマークされます。

私は '/ dev/null'への再オープンが正しい方法(tm)だとは思っていませんが、ここではstackoverflowの話題にはならないと思います。

申し訳ありません。