Perl: перенаправить вывод в файл и на консоль, сохранив код возврата - PullRequest
0 голосов
/ 09 февраля 2012

У меня проблема. В моем скрипте Perl я выполняю Java-программу, которая печатает как в stdout, так и в stderr потоки. Не могли бы вы дать мне совет, как я могу перенаправить stderr только в файл и stdout в тот же файл и на консоль Это не применимо, потому что мне также нужен код возврата Java-программы. Есть идеи?

Заранее спасибо!

Ответы [ 6 ]

3 голосов
/ 09 февраля 2012

Используйте IPC :: Open3 для вызова Java-программы. Используйте IO :: Select для чтения из файловых дескрипторов. Пиши сам.

IPC :: Open3 выполняет функции fork () и exec (), поэтому вы получите возвращаемое значение с помощью waitpid.

0 голосов
/ 10 февраля 2012

Bash включает опцию pipefail, чтобы конвейеры возвращали самый правый код ошибки вместо крайнего правого кода выхода.

Вы можете использовать что-то подобное для запуска команды в bash с pipefailнабор.

my $ret = system( q{bash -c 'set -o pipefail; java command 2>>~/test_file | tee -a ~/test_file'} );
0 голосов
/ 09 февраля 2012

Попробуйте сделать это следующим образом:

 perl -le 'qx(java -jar prog.jar>output.log 2>&1);$rc=$?;print "rc=",$rc<0 ? -1:$rc>>8'

Это перенаправит STDOUT и STDERR в ваш файл, захватит и напечатает код возврата.Проверьте (или cat) файл вывода на консоль при необходимости.Посмотрите на qx * ​​1006 * и system для получения дополнительной информации.

ОБНОВЛЕНИЕ: Другой способ - что-то вроде этого (то есть вторичная запись выходного файла):

my $msg=qx(java -jar prog.jar 2>&1);
my $rc=$? < 0 ? -1 : $? >>8, "\n";
print  $msg, "rc=$rc\n";
open my $fh, '>', 'output.log' or die "$!\n";
print  {$fh} $msg, "rc=$rc\n";
0 голосов
/ 09 февраля 2012

Вы не можете сделать это прямо из оболочки (без тройника).

Может быть, вы могли бы перенаправить файл, затем открыть этот файл из скрипта perl и распечатать на консоли. Что-то вроде:

use Path::Class; # Handy module, but you can do without

my $retvar = system("java -jar prog.jar >stdout.log 2>stderr.log ");

my $output = file('.', 'stdout.log')->slurp();
print $output; # or print STDERR $output;

Надеюсь, это немного поможет. Он по-прежнему хранит файл отдельно, а это, возможно, не то, что вы хотели.

Мишель.

0 голосов
/ 09 февраля 2012

Если вы находитесь под * nix, вам следует поискать команду "tee".

Вы, вероятно, должны сделать что-то вроде:

perl script.pl 2>stderr.out | tee stdout.out
0 голосов
/ 09 февраля 2012

Вы можете попробовать перейти, перенаправив stderr в стандартный вывод.

my $retvar = system("java -jar prog.jar 2>&1  > output.log ");
...