Допустим, я запускаю команду или сценарий оболочки, и он дает мне вывод. Не зная внутренностей этой команды или сценария оболочки, как определить, был ли вывод получен stderr
или stdout
?
Например,
$ ls -ld /
drwxrwxr-t 35 root admin 1258 Dec 11 19:16 /
против
ls -ld /test
ls: /test: No such file or directory
Как мне удостовериться, что первая команда напечатана, stdout
а вторая stderr
(сделана?)?
stderred
в свою оболочку окружение,LD_PRELOAD
чтобы получитьstdout
иstderr
разных цветов. Вот связанный вопрос в этом ключе.Ответы:
Невозможно сказать, когда результат уже напечатан. В этом случае оба
stdout
иstderr
подключены к терминалу, поэтому информация о том, в какой поток был записан, была уже потеряна к тому времени, как текст появился на вашем терминале; они были объединены программой прежде, чем когда-либо добирались до терминала.Что вы можете сделать, в таком случае , как выше, было бы запустить команду с
stdout
иstderr
перенаправлены в разные места и посмотреть , что происходит. Или запустите его дважды, один раз сstdout
перенаправленным на/dev/null
и один раз сstderr
перенаправленным на/dev/null
, и посмотрите, какой из этих случаев приводит к появлению текста.Вы можете перенаправить
stdout
к/dev/null
по лавируя>/dev/null
на конце командной строки, и вы можете перенаправитьstderr
к/dev/null
пути добавления2>/dev/null
.источник
Вы можете перенаправить стандартный вывод с помощью
> file
и перенаправить стандартный вывод с помощью2> file
. Многие современные оболочки поддерживают перенаправление на команды, поэтому вы можете использоватьsed
для выделения того, какой вывод поступает из какого потока:источник
(echo "this is stdout"; echo "this is stderr" >&2) > >(sed 's/.*/\x1b[32m&\x1b[0m/') 2> >(sed 's/.*/\x1b[31m&\x1b[0m/')
annotate-output
Скрипт из Debian - хdevscripts
позволяет делать это выборочно:Во втором столбце указаны stdout и stderr с
O
иE
соответственно.Есть несколько предостережений, главное из которых было отмечено в других ответах: вы не можете сделать это после факта. Ни оболочка, ни терминал не знают, как произвольная программа использует свои файловые дескрипторы, хотя оболочка отвечает за их первоначальную настройку.
Этот метод использует fifo, запись в fifo может вести себя иначе, чем запись в tty, и запись в два разных fifo определенно отличается (потенциальные проблемы синхронизации / чередования). Кроме того, он не подходит для интерактивного использования, например,
annotate-output bash
это не очень хороший план, но он полезен для многих других целей. Существует множество примеров сценариев и функций оболочки в ответах на связанные вопросы о раскрашивании stdin / stdout / stderr. Самый надежный из них - это stderrd, который использует модификацию времени выполнения (большинства) программ для изменения данных, записанных в stderr.На этот вопрос, на который ссылается Anko, есть хорошие ответы по этой связанной теме: раскраска вывода stdout / stderr: могу ли я настроить свою оболочку для печати STDERR и STDOUT разными цветами?
источник
bash
скрипт, использующийwhile read
циклы и запускающий однуdate
команду для каждой строки stdout или stderr, поэтому он будет намного менее эффективным, чемcmd > >(ts '%T O:') 2> >(ts '%T E:')
эквивалентный.Помимо других ответов, интересно указать
/proc/$PID/fd
(хотя и не отвечает на вопрос):Как видите, здесь вы можете увидеть файловые дескрипторы, открытые для процесса.
0
этоSTDIN
,1
этоSTDOUT
и2
естьSTDERR
. Если вы не перенаправили STDOUT или STDERR, вы увидите/dev/pts/33
(по крайней мере, в этом примере), потому что они будут указывать на терминал.примечания :
/proc/$PID
существует только для запущенных процессов. В этом случае я использовалcat
без аргументов, поэтому он не заканчивается, пока я не закроюSTDIN
. Я также выполнил это в фоновом режиме, поэтому у меня есть PID немедленно для примера.источник
Не совсем понятно, о чем вы спрашиваете, но это может помочь
Источник
Если код выхода равен 0, это просто означает, что команда выполнена правильно (stdout), здесь вы можете найти значения, если код выхода отличается от 0 (stderr)
источник
stdout
а ненулевойstderr
?stderr
и возвращать хороший код ошибки или писатьstdout
и возвращать плохой код ошибки. На самом деле, попробуйтеfind /root
- при условии, что вы не работаете от имени пользователя root, вы должны распечатать две строки - «/ root» будет напечатаноstdout
, а «find: / root: Permission denied» будет напечатаноstderr
. И найти возвращает неверный код возврата.Обычно STDERR будет иметь имя программы, добавленное к сообщению с двоеточием.
Пример:
Vs
источник
Для захвата и проверки вывода ошибок:
источник