Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为什么在生成守护进程时utf8 IO层会被剥离?_Perl_Encoding_Utf 8 - Fatal编程技术网

Perl 为什么在生成守护进程时utf8 IO层会被剥离?

Perl 为什么在生成守护进程时utf8 IO层会被剥离?,perl,encoding,utf-8,Perl,Encoding,Utf 8,以下代码按预期工作: use feature qw(say); use strict; use warnings; use open qw/:std IN :encoding(utf-8) OUT :utf8/; say join ' ', (PerlIO::get_layers(\*STDOUT)); my $pid = fork(); die "fork() failed: $!" unless defined $pid; if ($pid == 0) { say join

以下代码按预期工作:

use feature qw(say);
use strict;
use warnings;
use open qw/:std IN :encoding(utf-8) OUT :utf8/; 

say  join ' ', (PerlIO::get_layers(\*STDOUT));
my $pid = fork();
die "fork() failed: $!" unless defined $pid;
if ($pid == 0) {
    say  join ' ', (PerlIO::get_layers(\*STDOUT));
}
输出

unix perlio utf8
unix perlio utf8
但如果我使用守护进程而不是常规fork:

use feature qw(say);
use strict;
use warnings;
use open qw/:std IN :encoding(utf-8) OUT :utf8/; 
use Cwd qw(getcwd);
use Proc::Daemon;

my $work_dir = getcwd;    
my $daemon = Proc::Daemon->new(
    work_dir     => $work_dir,
    child_STDOUT => 'stdout.txt',
    child_STDERR => 'stderr.txt',
    pid_file     => 'pid.txt',
);
my $pid = $daemon->Init();
if ( $pid == 0 ) {
    say  join ' ', (PerlIO::get_layers(\*STDOUT));
}
文件
stdout.txt
的输出为:

unix perlio
因此,
utf8
IO层已被剥离。

考虑以下示例:

下午六时

package Foo;
use warnings;
use strict;
sub test {
  close STDIN;
  open \*STDIN, "<", "/dev/null";
}
1;

看起来
使用open
与其他杂注类似,只适用于其中的文件。因此,当
Proc::Daemon
关闭标准输入、输出和错误并重新打开它们时,它自然看不到额外的层。

如中所述,该模块关闭stdin等并重新打开它们。我不确定,但我打赌
open
pragma在词汇范围上与大多数其他语言一样;在一个包中设置它不会改变其他包的工作方式。
use open
是词汇范围。(除了
:std
部分,它会导致立即调用
binmode
#!/usr/bin/perl
use strict;
use warnings;
use feature qw/say/;
use open qw/:std IN :encoding(UTF-8) OUT :encoding(UTF-8)/;
use lib qw/./;
use Foo;

$, = ' ';
say "Original STDIN:", PerlIO::get_layers(\*STDIN);
close STDIN;
open \*STDIN, "<", "/dev/null";
say "Reopened STDIN:", PerlIO::get_layers(\*STDIN);
Foo::test();
say "Reopened STDIN in different package:", PerlIO::get_layers(\*STDIN);
$ perl test.pl
Original STDIN: unix perlio encoding(utf-8-strict) utf8
Reopened STDIN: unix perlio encoding(utf-8-strict) utf8
Reopened STDIN in different package: unix perlio