не удалось сгенерировать ошибку и перенаправить ее в файл в Perl

Я пытаюсь перенаправить свои STDOUT и STDERR в какой-то файл. У меня это получается в какой-то степени. Но я не могу понять одну вещь в приведенном ниже коде.

#!/usr/bin/perl
open (STDOUT,">/var/tmp/outfile") or die "problem : $!";
open (STDERR,">>/var/tmp/outfile") or die "problem : $!";
print "$_\n" foreach (1..10);
sdsdf;  # buggy line inserted wantedly

Я вставил последнюю строку, предполагая, что Perl выдаст ошибку, и она будет перенаправлена ​​в файл, но этого не происходит. Моя программа не выводит никаких ошибок ни на экран, ни в выходной файл. Пожалуйста, помогите мне понять это поведение.


person chidori    schedule 25.02.2013    source источник
comment
@Krishna: Вопрос объясняет, почему он это добавил: я вставил последнюю строку, предполагая, что Perl выдаст ошибку, и она будет перенаправлена ​​в файл, но этого не происходит. Он предназначен для тестирования STDOUT путем создания ошибки времени выполнения (... что лучше сделать, используя warn или die). Использование strict противоречило бы этой цели, поскольку оно вообще препятствовало бы запуску программы.   -  person Dave Sherohman    schedule 25.02.2013


Ответы (2)


Без use strict;,

 sdsdf;

такой же как

 "sdsdf";

Это одна из причин, по которой вы всегда хотите использовать use strict; use warnings;. Давайте начнем с добавления этого.


Итак, вы хотите регистрировать весь вывод, включая ошибки времени компиляции, в файл. Что ж, этого не произойдет, перенаправив STDERR после того, как ваш код будет скомпилирован. Лучший способ сделать это вне вашей программы.

script.pl >/var/tmp/outfile 2>&1

но это можно сделать из вашей программы.

#!/usr/bin/perl
use strict;
use warnings;

BEGIN {
   open(STDOUT, '>', '/var/tmp/outfile')
      or die("Can't redirect STDOUT: $!\n");
   open(STDERR, '>&', \*STDOUT)
      or die("Can't redirect STDERR: $!\n");
}

print "$_\n" foreach (1..10);
sdsdf;  # Syntax error
person ikegami    schedule 25.02.2013
comment
не могли бы вы объяснить, что происходит в этой строке open(STDERR, '>&=', \*STDOUT) я не понимаю = и *STDOUT - person chidori; 26.02.2013
comment
*STDOUT — это имя переменной, а \*STDOUT — дескриптор файла, известный как стандартный вывод, где print $x; обычно отправляет свои данные. >&= вызывает открытие STDERR с тем же файловым дескриптором, что и STDOUT, что на самом деле плохо. (Но, к счастью, это не сработало, потому что STDERR не был закрыт.) Исправлено. - person ikegami; 26.02.2013
comment
в коде about я могу просто использовать open(STDERR, '>&', STDOUT), верно? не понимаю использования \* после STDOUT . Я попытался выполнить этот код с \* и без него после STDOUT, и это дало мне один и тот же результат. - person chidori; 26.02.2013
comment
Он может понять, что вы имеете в виду \*STDOUT, когда говорите STDOUT. Я не пробовал. - person ikegami; 26.02.2013

sdsdf не генерирует никаких ошибок (если вы use strict, то вы увидите некоторые ошибки времени компиляции), поэтому вы не видите никаких сообщений. Попробуй это:

use warnings;
use strict;
open (STDOUT,">outfile1") or die "problem : $!";
open STDERR, ">&STDOUT";
print "$_\n" foreach (1..10);
die("aaaa");  # buggy line inserted wantedly

Также в вашем коде вы открываете один и тот же файл дважды, это может вызвать некоторые проблемы. В приведенном выше примере мы сначала перенаправляем стандартный вывод в файл, а затем перенаправляем стандартный вывод в стандартный вывод.

person perreal    schedule 25.02.2013
comment
извини но я не понимаю! Perl не должен выдавать ошибку, поскольку он не сможет скомпилировать код из-за неизвестного ключевого слова. я знаю, что переключатель предупреждения печатает предупреждающее сообщение, но почему интерпретатор Perl не говорит что-то об этой неправильной строке? - person chidori; 25.02.2013
comment
Потому что голое слово sdsdf интерпретируется как строка, а строка в строке ничего не делает для генерации вывода и не является ошибкой. Похоже на наличие 123123; в строке. - person perreal; 25.02.2013
comment
Вы можете увидеть предупреждение о бесполезном использовании константы, если вы use warnings. - person perreal; 25.02.2013
comment
хорошо, если я включу use warnings, я выведу несколько сообщений на свой экран, но не могли бы вы сказать мне, как перенаправить их в файл? не являются ли эти предупреждающие сообщения частью STDERR? Если нет, то чем они отличаются? - person chidori; 25.02.2013