Ради читателя (поскольку OP уже "заработал"):
В документации Perl "perlopentut" (perldoc perlopentut) приводятся примеры открытия альтернативного дескриптора файла, направленного на STDOUT, но в нем используется голое словофайловые дескрипторы и версия с двумя аргументами open
, обе из которых несколько древние.В книге Дамиана Конвея "Perl Best Practices" (а также Perl :: Critic, основанной на книге Дамиана) подчеркивается использование трех открытий arg и лексических файловых дескрипторов (файловые дескрипторы стиля my $foo
).В «Современном Perl» chromatic также кратко упоминается использование лексических файловых дескрипторов, и там, где это практически возможно, не рекомендуется использовать голые слова.Три arg open
считается более безопасной формой, поскольку ограничивает воздействие инъекций оболочки.Несмотря на то, что в данном случае речь идет о малом риске, по-прежнему хорошей привычкой является использование по умолчанию трех аргументов open
.
. Необходимо внимательно прочитать примеры, показанные в документации open
Perl (perldoc -f open), и небольшая интерпретация, чтобы заметить правильное размещение символа амперсанда при открытии дубликата фила-ручки, направленной на STDOUT
при использовании трехарговой версии open
.Можно ошибочно предположить, что это должно работать: open my $fh, '>', '&STDOUT' or die $!;
, главным образом потому, что это выглядит как формат, который мы привыкли видеть (амперсанд перед именем символа).Но этот синтаксис не тот, что нужен open
, и мы привыкли видеть его в совершенно ином контексте: некоторые вызовы подпрограмм.
Правильный способ открыть дуплекс для STDOUT
с тремяarg open
состоит в том, чтобы объединить >
и &
в один и тот же второй аргумент и оставить STDOUT пустым, например:
use Modern::Perl;
open my $fh, '>&', STDOUT or die "Bleah: $!";
say $fh 'Printing alternate filehandle "$fh" worked.';
say 'Implicitly printing to "STDOUT" also works.';
или передать STDOUT
в open
какссылка на typeglob:
open my $fh, '>&', \*STDOUT or ...