2013-02-25 1 views
0

Я пытаюсь перенаправить STDOUT и STDERR в какой-то файл. В какой-то степени я добился успеха. Но я не могу понять одну вещь в приведенном ниже коде.не удалось создать ошибку и перенаправить ее в файл в perl

#!/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 будет разлетом ошибки и будет перенаправлен в файл, но его не происходит. Моя программа не распространяется на любую ошибку на экране или в outfile. Пожалуйста, помогите мне понять это поведение.

+0

@Krishna: Вопрос объясняет, почему он добавил его: «Я вставил последнюю строку в предположении, что Perl будет разлетом ошибки и будет перенаправлен в файл, но его не происходит.» Он предназначен для тестирования STDOUT, создавая ошибку времени выполнения (... что было бы лучше сделать с помощью 'warn' или' die'). Использование 'strict' будет противодействовать этой цели, так как это предотвратит запуск программы вообще. –

ответ

1

Без 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 
+0

Не могли бы вы объяснить, что происходит в этой строке? Open (STDERR, '> & =', \ * STDOUT) 'Я не получаю' = 'и' * STDOUT' – chidori

+0

'* STDOUT' - это имя переменная и '\ * STDOUT' - это дескриптор файла, известный как« стандартный вывод », где' print $ x; 'обычно отправляет свои данные. '> & =' вызывает открытие STDERR с тем же файловым дескриптором, что и STDOUT, что на самом деле плохо. (Но, к счастью, не работает, потому что STDERR не был закрыт.) Исправлено. – ikegami

+0

в коде о том, что я могу просто пойти с 'open (STDERR, '> &', STDOUT)' right? не понимая использования '\ *' после 'STDOUT'.Я попытался выполнить этот код с и без '\ *' после того, как 'STDOUT' оба дали мне тот же результат. – chidori

2

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 

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

+0

извините, но я не понимаю! не следует переписывать ошибку perl, поскольку она не сможет скомпилировать код из-за неизвестного ключевого слова. Я знаю, предупреждающий переключатель печатает предупреждающее сообщение, но почему бы не интерпретировать интерпретатор perl что-то об этой неправильной строке? – chidori

+0

Поскольку bareword 'sdsdf' интерпретируется как строка, а строка в строке ничего не делает для генерации вывода, и это не ошибка. Аналогично тому, как '123123;' на линии. – perreal

+0

Вы можете увидеть предупреждение «бесполезное использование константы», если вы используете предупреждения. – perreal