Скопируйте весь вывод сценария Perl в файл - PullRequest
1 голос
/ 27 октября 2009

Я хотел бы скопировать stdout и stderr моего Perl-скрипта в файл, сохранив его также на экране и предпочтительно используя какой-то трюк внутри самого скрипта. То есть Я хочу что-то похожее на

. / Test.pl 2> & 1 | тройник foo.bar

но скрыто внутри реализации скрипта perl. На данный момент я только что написал подпрограмму, которая печатает все сообщения как на экране, так и в дескрипторе файла, но недостатком является то, что если сценарий умирает, сообщение die не будет отображаться в журнале. Есть ли способ сделать это?

Ответы [ 5 ]

7 голосов
/ 27 октября 2009

См. Раздел «13.15.9. Пример связи: файловые дескрипторы с несколькими приемниками» в поваренной книге Perl.

Главное знать это tie *TEE, "Tie::Tee", @handles;

ПРИМЕЧАНИЕ: пакет Tie :: Tee - это то, что вам нужно создать самостоятельно, код находится в том же разделе книги.

ПРИМЕЧАНИЕ: затем вы можете сделать select(TEE), и он будет использоваться в каждом регулярном print выражении, поэтому вам не нужно делать print TEE xxx.

ПРИМЕЧАНИЕ. Чтобы любой вывод STDERRy (включая die) перешел на тот же файловый дескриптор, измените STDERR на TEE следующим образом:

use Tie::Tee; 
use Symbol; 
@handles = (*STDOUT); 
push(@handles, $handle = gensym( )); 
open($handle, ">/tmp/teetest.xxx"); 
tie *TEE, "Tie::Tee", @handles; 
select(TEE); 
*STDERR = *TEE; 
print "raw print\n"; 
die "XXXX\n";

Вывод будет:

raw print
XXXX

И содержимое файла будет:

raw print
XXXX
4 голосов
/ 27 октября 2009

Взгляните на Журнал :: Отправка
Отправляет сообщения на один или несколько выходов.

   use Log::Dispatch;

   # Simple API
   #
   my $log =
       Log::Dispatch->new
           ( outputs =>
                 [ [ 'File',   min_level => 'debug', filename => 'logfile' ],
                   [ 'Screen', min_level => 'warning' ],
                 ],
           );

   $log->info('Blah, blah');

   # More verbose API
   #
   my $log = Log::Dispatch->new();
   $log->add( Log::Dispatch::File->new
                         ( name      => 'file1',
                           min_level => 'debug',
                           filename  => 'logfile'
                         )
                   );
   $log->add( Log::Dispatch::Screen->new
                         ( name      => 'screen',
                           min_level => 'warning',
                         )
                   );

   $log->log( level => 'info', message => 'Blah, blah' );

   my $sub = sub { my %p = @_; return reverse $p{message}; };
   my $reversing_dispatcher = Log::Dispatch->new( callbacks => $sub );

В нем есть несколько вспомогательных / служебных модулей, на которые вы тоже должны обратить внимание.

Log :: Dispatch :: DBI - Записать вывод в таблицу базы данных.

Log :: Dispatch :: FileRotate - периодически поворачивает файлы журнала как часть его использование.

Журнал :: Отправка :: Файл :: Штамп - Журнал штампов файлы с информацией о дате и времени.

Журнал :: Отправка :: Jabber - Журналы сообщения через Jabber.

Журнал :: Отправка :: Tk - Журналы сообщения в окно Tk.

Log :: Dispatch :: Win32EventLog - Журналы сообщения в журнал событий Windows.

Log :: Dispatch :: Config - Позволяет настройка логирования через текст файл похож (или так мне сказали), как это делается с log4j.

1 голос
/ 28 октября 2009

В зависимости от размера вашего сценария, я настоятельно рекомендую Log :: Log4perl ... сохраняет повторную реализацию журнала каждый раз, когда вы пишете сценарий.

Если вы используете Log4perl в простом режиме, он добавляет всего около 10 строк кода и очень полезен.

Log4perl чрезвычайно гибок в перенаправлении вывода практически в любое место, включая несколько выходов одновременно.

0 голосов
/ 27 октября 2009
0 голосов
/ 27 октября 2009

Это звучит как то, что вам нужно, к сожалению, это bash-скрипт, и вы бы хотели, чтобы все это обрабатывалось в вашем perl-коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...