Как сказать, является ли вывод командного сценария или сценария оболочки stdout или stderr

В мире Unix/Linux Вы не найдете инструменты, которые "делают все", поскольку это нарушает единственный принцип ответственности. Однако для "организования" всех инструментов вместе в единственной панели конфигурации существуют проекты как Webmin, которые обеспечивают эту функциональность. Для этой определенной задачи почты/программного обеспечения для совместной работы у меня есть следующее предложение.

Вы могли посмотреть на Комплект Сотрудничества Zarafa (ZCP) в сочетании с Постфиксом и Z-администратором. Это всего один из многих других опций.

ZCP предлагает все 'функции', Постфикс сделает, работа MTA и Z-администратор способны к управлению и конфигурированию всех сервисов (также MySQL и сетевые интерфейсы) в хорошем веб-интерфейсе. Прочитайте Z-администраторские документы здесь, чтобы видеть, соответствует ли это Вашим потребностям.

Отказ от ответственности: Я работал на Zarafa в прошлом.

32
24.02.2015, 00:10
8 ответов

Нет возможности сказать, как только вывод уже напечатан. В этом случае оба stdout и и подключены к клемме . Они были объединены программой, прежде чем когда-либо добиться ее до терминала.

Что вы можете сделать, в том случае, как вышеизложенное, будет запустить команду с помощью stdout и и , перенаправляемый в разные места и посмотреть, что происходит. Или пробежать его дважды, один раз с stdout , перенаправленные на / dev / null и один раз с STDERR перенаправлено на / dev / null , и Посмотрите, какие из этих случаев приводит к появлению текста.

Вы можете перенаправить stdout на / dev / null путем присоединения > / dev / null в конце командной строки, и вы можете перенаправить Стдерр к / DEV / NULL путем добавления 2> / dev / null .

19
27.01.2020, 19:37

Это не совсем понятно, что вы спрашиваете, но это может помочь

ls -ld /
echo $?    # Exit status 0 returned because command executed successfully.

ls -ld /test
echo $?    # Non-zero exit status returned -- command failed to execute

источника

Код 0 Это просто означает, что команда выполняется правильно (stdout), здесь Вы можете найти значения, если код выхода отличается от 0 (STDERR)

[
0
27.01.2020, 19:37

Вы можете перенаправить stdout с помощью > file, а stderr - с помощью 2> file. Многие современные оболочки поддерживают перенаправление на команды, поэтому Вы можете использовать sed для подсветки того, какой вывод поступает из какого потока:

$ ls 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
1: unity_support_test.0
1: vmwareDnD

$ ls foo 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
2: ls: cannot access foo: No such file or directory
10
27.01.2020, 19:37

Скрипт annotate-output из devscripts Debian позволяет делать это выборочно:

$ annotate-output ls -ld /test
14:54:22 -: Started ls -ld /test
14:54:22 E: ls: cannot access /test: No such file or directory
14:54:22 -: Finished with exitcode 2

Во второй колонке указаны stdout и stderr с помощью O и E, соответственно.

Существуют некоторые предостережения, главное из которых, как отмечено в других ответах: вы не можете сделать это после факта. Ни оболочка, ни терминал не знают, как произвольная программа использует свои файловые дескрипторы, хотя оболочка изначально отвечает за их настройку.

Этот метод использует fifos, запись в fifo может вести себя иначе, чем запись в tty, а запись в два разных fifos определенно отличается (потенциальные проблемы с синхронизацией/интерлейвалом). Кроме того, он не подходит для интерактивного использования, например, annotate-output bash - не очень хороший план, но он полезен для многих других целей. Существует множество, множество примеров скриптов и функций оболочки в ответах на связанные с этим вопросы о раскраске stdin/stdout/stderr, наиболее робастным является stderrd, который использует модификацию (большинства) программ во время выполнения для модификации данных, записанных в stderr.

На этот вопрос, на который ссылается Анко, есть хорошие ответы на эту смежную тему: окрашивание вывода stdout/stderr: Могу ли я настроить оболочку на печать STDERR и STDOUT разными цветами?

5
27.01.2020, 19:37

Помимо других ответов, он является целым числом, указывающим на /proc/$PID/fd (хотя он не отвечает на вопрос):

$ cat > /dev/null 2> /tmp/blablah &
[1] 3073

[1]+  Stopped                 cat > /dev/null 2> /tmp/blablah
$ ls -l /proc/3073/fd
total 0
lrwx------ 1 kampde kampde 64 Feb 24 11:43 0 -> /dev/pts/33
l-wx------ 1 kampde kampde 64 Feb 24 11:43 1 -> /dev/null
l-wx------ 1 kampde kampde 64 Feb 24 11:43 2 -> /tmp/blablah

Как видите, здесь вы можете увидеть дескрипторы файлов, открытых для процесса. 0 - это STDIN, 1 - это STDOUT и 2 - это STDERR. Если бы вы не перенаправили STDOUT или STDERR, вы бы увидели /dev/pts/33 (по крайней мере, в данном примере), потому что они будут указывать на клемму.

примечания: /proc/$PID существует только для запущенных процессов. В данном случае я использовал cat без аргументов, поэтому он не заканчивается до тех пор, пока я не закрою STDIN. Я также выполнил его в фоновом режиме, поэтому я немедленно получил PID для этого примера.

1
27.01.2020, 19:37

Для захвата и проверки на наличие ошибок на выходе:

ls -l test 2>errors
if [ -s errors ]; then echo "There were errors:" && cat errors; fi
rm errors
-1
27.01.2020, 19:37

Обычно в STDERR к сообщению добавляется двоеточие перед именем программы.

Пример:

rpm -zq some_utils 
rpm: -zq: unknown option

Против

rpm -ql some_utils 
package some_utils is not installed
-1
27.01.2020, 19:37

Вы можете легко использовать grep для этого:

$ ls -l test | grep.
ls: cannot access 'test': No such file or directory

Это предполагает, что ваш вывод grep окрашен (это значение по умолчанию в большинстве дистрибутивов ).

Это приведет к выделению stdoutцветом grep по умолчанию, например:

$ (echo "this is stdout"; echo "this is stderr" >&2) | grep.
this is stderr
this is stdout

Первая строка вывода — белая, а вторая — цветная. Это может быть противоположно тому, что вы хотите, если ваш цвет grep по умолчанию красный. Если вы явно хотите установить для stdoutзеленый цвет, вы можете сделать это, чтобы установить цвета grep на зеленый:

$ GREP_COLORS='ms=01;32'
$ (echo "this is stdout"; echo "this is stderr" >&2) | grep.

Если вы явно хотите получить красный вывод дляstderr:

$ GREP_COLORS='ms=01;31'
$ (echo "this is stdout"; echo "this is stderr" >&2) 2> >(grep.)

Если вы действительно хотите, чтобы и stderr, и stdout были определенными цветами, вы можете сделать это:

$ (echo "this is stdout"; echo "this is stderr" >&2) 2> >(GREP_COLORS='ms=01;31' grep.) 1> >(GREP_COLORS='ms=01;32' grep.)
0
14.04.2021, 00:08

Теги

Похожие вопросы