Как трубу stderr без трубопровода stdout
Как передать стандартный поток ошибок, не передавая стандартный поток вывода?
Я знаю, что эта команда работает, но она также записывает стандарт.
Command 2>&1 | tee -a $LOG
Как получить только стандартную ошибку?
Примечание. Из этого я хочу просто записать поток stderr в журнал и записать как stderr, так и stdout в консоль.
4 ответа
Для этого используйте один дополнительный файловый дескриптор для переключения stderr и stdout:
find /var/log 3>&1 1>&2 2>&3 | tee foo.file
В принципе, это работает, или, по крайней мере, я думаю, что это работает следующим образом:
Направления оцениваются слева направо.
3>&1
Создает новый файловый дескриптор, 3 дубликат (копия) из fd 1 (стандартный вывод).
1>&2
Сделайте stdout (1) дубликатом fd 2 (stderr)
2>&3
Сделайте fd 2, копию (копию) 3, которая ранее была сделана копией stdout.
Так что теперь stderr и stdout переключаются.
| tee foo.file
дублирует дескриптор файла 1, который был преобразован в stderr.
Unix/Linux команда Кайла переключает STDERR с STDOUT; однако объяснение не совсем верно. Операторы перенаправления не выполняют никакого копирования или дублирования, они просто перенаправляют поток в другое направление.
Переписав команду Кайла, временно переместив 3>&1 в конец, упростит понимание концепции:
find /var/log 1>&2 2>&3 3>&1
Тем не менее, в таком случае Linux будет отображать ошибку, поскольку &3 еще не существует, так как он расположен до 3>&1. 3> что-то - это способ объявить (определить), что мы собираемся использовать третью трубу, поэтому она должна быть расположена до того, как мы потечем воду в эту трубу, например, так, как это написал Кайл. Попробуйте этот другой способ просто для удовольствия:
((echo "STD1"; anyerror "bbbb"; echo "STD2" ) 3>&1 4>&2 1>&4 2>&3) > newSTDOUT 2> newSTDERR
Не иметь возможности делать копии - это позор. Вы не можете делать такие вещи, как "3>&1 3>&2" в одной команде, потому что Linux будет использовать только первый найденный и отклонит второй.
Я (пока) не нашел способа отправить как ошибку, так и обычный вывод в файл, а также отправить копию ошибки на стандартный вывод одной командой. Для instace у меня есть задание cron, в котором я хочу, чтобы оба вывода (error и standard) заносились в файл журнала и позволяли также сообщать об ошибке, чтобы отправить электронное сообщение на мой blackBerry. Я могу сделать это с помощью двух команд, используя "tee", но ошибка не отображается в правильном порядке среди обычной строки вывода в файле. Это уродливый способ, которым я решил проблему:
((echo "STD1"; sdfr "bbbb"; echo "STD2" ) 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1
Обратите внимание, что я должен использовать log1 дважды, и я должен добавить в обоих случаях, первый из которых использует опцию "-a" для команды "tee", а второй - ">>".
Делая кошку log1 вы получаете следующее:
STD1
STD2
-bash: sdfr: command not found
Обратите внимание, что ошибка не отображается во второй строке, как следует.
Согласно man-странице для ksh (pdksh), вы можете просто сделать:
Команда 2>&1 >/dev/null | кот-н
то есть dup stderr в stdout, перенаправьте stdout в /dev/null, затем перенаправьте в 'cat -n'
работает на pdksh в моей системе:
$ errorecho () {echo "$ @"> & 2;} $ errorecho foo Foo $ errorecho foo> / dev / null # должен отображаться даже с перенаправленным stdout Foo $ errorecho foo 2>&1 >/dev/null | кот-н 1 фу $
Я запустил его так, как ты когда-либо хотел, так как я тоже нуждался в этом и усовершенствовал твою команду Теперь для меня это работает правильно, используя Bash 3.2 на Debian Squeeze с помощью этого
(echo "foo" 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1 >> log2
в то время как log1 регистрирует stdout и stderr, а log2 регистрирует только stderr и ничего больше не выводит на экран.