#perl #encoding #utf-8
#perl #кодирование #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 ' ', (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
, слой ввода-вывода удален.
Комментарии:
1. Как указано в документации , этот модуль закрывает stdin и т. Д. И снова открывает их. Я не знаю наверняка, но держу пари
open
, что pragma имеет лексическую область действия, как и большинство других; установка его в одном пакете не меняет работу других пакетов.
Ответ №1:
Рассмотрим этот пример:
Foo.pm:
package Foo;
use warnings;
use strict;
sub test {
close STDIN;
open *STDIN, "<", "/dev/null";
}
1;
test.pl:
#!/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
Looks like use open
похож на другие прагмы и применяется только к файлу, в котором он находится. Поэтому, когда Proc::Daemon
закрываются стандартные ввод, вывод и ошибка и снова открываются, он, естественно, не видит дополнительных слоев.
Комментарии:
1.
use open
имеет лексическую область действия. (Кроме:std
части, которая вызываетbinmode
немедленный вызов)