проблемы при перенаправлении stderr в csh - PullRequest
3 голосов
/ 19 апреля 2011

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

my $out = `cmd`

, но он не захватывает STDERR, который мне тоже нужен.Запуск sh с перенаправлением вывода ничего не делает

my $out = `sh -c "cmd 2>&1"`

по-прежнему захватывает только STDOUT, а не STDERR.

Даже перенаправление на файл в csh не работает для меня

tcsh$ cmd >& logfile.log

по-прежнему захватывает только STDOUT%)

Команда, которую я пытаюсь выполнить, является действительнойскрипт и некоторые команды в этом скрипте печатаются в STDERR, и я хочу записать этот вывод.Если я выполняю sh -c "cmd 2>/dev/null" STDERR фактически переходит в / dev / null и в терминале печатается только STDOUT.

Может ли кто-нибудь помочь мне с этим?

Ответы [ 6 ]

1 голос
/ 24 июля 2011

У меня нет времени, чтобы смоделировать пример, как обычно, и даже не протестировать.Я думаю, что вы можете попробовать использовать Capture::Tiny, чтобы посмотреть, поможет ли это.

1 голос
/ 24 июля 2011

Вы сказали, что выполнение команды cmd >& logfile.log в tcsh отправляет только stdout cmd в файл журнала, а не его stderr.Это не имеет смысла.

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

#!/bin/sh

echo stdout
echo STDERR 1>&2

В logfile.log должны отображаться как "stdout", так и "STDERR".

Если так, то, возможно, ваш "cmd" делает что-то странное.Мое лучшее предположение - то, что cmd пишет в / dev / tty, а не в stdout или stderr;это не повлияет на перенаправление.

Чтобы понять, что я имею в виду, добавьте эту строку в скрипт выше:

echo tty > /dev/tty
1 голос
/ 21 апреля 2011

Я верю, что вы о чем-то нам не говорите. Вы на Cygwin? Или винда? У вас есть переменная окружения PERL5SHELL?

Есть что-то, о чем вы нам не говорите, потому что оба они отлично работают на пяти платформах, на которых я могу легко протестировать:

% perl -le '$out = `sh -c "grep missing /dev/nowhere 2>&1" | cat -n`; chomp $out; print "got <<<$out>>>"'
got <<<     1   grep: /dev/nowhere: No such file or directory>>>

Но в действительности нет никаких оснований вызывать sh (1) явно для обстрела. Это потому, что Perl всегда вызывает sh (1) для всех своих обратных тиков, открытия канала и system() оболочки:

% perl -le '$out = `grep missing /dev/nowhere 2>&1 | cat -n`; chomp $out; print "got <<<$out>>>"'
got <<<     1   grep: /dev/nowhere: No such file or directory>>>

Единственное, кроме этого, что я могу придумать, происходит в не-Unix системах, где, поскольку у них нет / bin / sh , определено что-то еще.

Но ни при каких условиях простые вывески не будут вызывать tcsh (1) за вашей спиной. Вы должны были серьезно взломать источник perl (1), чтобы это произошло. Я также сомневаюсь, что вы могли (легко) взломать двоичный файл, поскольку строка "/bin/tcsh" будет длиннее "/bin/sh", и ее не очень часто можно найти в / bin / в любом случае.

То, что перенаправление stderr не работает даже из оболочки, говорит о том, что происходит что-то довольно странное. Я думаю, что нам нужно больше информации.

1 голос
/ 21 апреля 2011

Я сталкивался с тем же вопросом.И после проведения небольшого исследования я встретил этот пост: Capture stderr, а также stdout из tcs .Внизу этого поста автор разобрался со своим обходным путем, что также соответствовало моему требованию.Я думаю, что вы можете дать ему шанс.Это может приятно объединить выходные данные stderr и stdout.

1 голос
/ 19 апреля 2011
  • Захват обратных кавычек STDOUT, а не STDERR.
  • system выведет как stdout, так и stderr в настройки их родителей.
  • Если вы хотите захватить STDERR, вам нужно что-то вроде IPC::Open3:

Очень похоже на open2 () , open3 () порождает указанный $ cmd и подключает CHLD_OUT для чтения от ребенка, CHLD_IN для записи ребенку и CHLD_ERR для ошибок , Если CHLD_ERR равен false,

1 голос
/ 19 апреля 2011

Здесь вы захватываете STDOUT sh, который не является STDERR cmd:

my $out = `sh -c "cmd 2>&1"`;

Можете ли вы просто запустить cmd напрямую?

my $out = `cmd 2>&1`;
...