Как подавить вывод команды, но показать ее, если команда выхода кодирует ошибку?
3 ответа
К сожалению, предположение, что stderr используется только для вывода ошибок, не всегда верно. Скорее, stderr часто используется для любого и всех интерактивных выводов и диагностики, т.е. выводов, предназначенных для чтения пользователем в интерактивном приглашении 1. wget и dd - известные примеры.
Некоторые команды предоставляют флаг (например, -quiet или -silent) для подавления вывода без ошибок - прочитайте их справочные страницы, чтобы увидеть, существует ли он.
Другое соглашение, которое выполняется чаще, - это код выхода: программа возвращает код выхода при выходе. Как правило, 2, код выхода 0 указывает на успех, а любой другой код выхода указывает на ошибку.
С помощью bash вы можете получить код выхода последней команды из $? переменная. В fish используйте переменную $status . Вы можете передать stderr во временный файл и распечатать его только в случае возникновения ошибки. Например (fish):
command 2>/tmp/outputbuffer
if $status
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Вы также можете использовать некоторые сочетания клавиш, если вы не объединяете команды:
if command 2>/tmp/outputbuffer
cat /tmp/outputbuffer
rm /tmp/outputbuffer
Или же:
command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;
Вы также можете направить стандартный stdout в тот же буфер, используя 2>&1 >/tmp/outputbuffer .
(Примечание: я на самом деле не знаю fish , поэтому я адаптирую концепцию к тому, что я могу найти в ее документации. Синтаксис может быть немного неправильным. Также вы можете использовать mktemp для генерации уникального временного файла - запустите его и запишите имя файла в переменной.)
Если вам нужно запустить все это одновременно в фоновом режиме оболочки, которую вы также используете в интерактивном режиме, то вам лучше написать сценарий для обработки сокрытия вывода и запустить этот сценарий в фоновом режиме с помощью стандартных приемов. (fish). Черт возьми, вы можете поместить что-то вроде следующей функции в ~/.config/fish/config.fish:
function run-silent
set temp (mktemp)
if $argv 2>&1 >$temp
cat $temp
rm $temp
end
Вызов с run-silent somecommand & (где трейлинг & заставляет его работать в фоновом режиме)
Обратите внимание, что это поглотит исходный код завершения и сбросит как stdout и stderr в случае сбоя. Вы можете настроить его по мере необходимости.
1 Нет даже гарантии, что вывод ошибок не появится на stdout - некоторые программы будут выводить весь вывод там!
2 К сожалению, это не всегда так - код выхода полностью контролируется программой, а некоторые укажут некоторые условия успеха с ненулевыми выходами. Снова, проверьте руководство.
Утилиты Unix отправляют общие сообщения в stdout , а сообщения об ошибках - в stderr , поэтому, если мы хотим видеть только сообщения об ошибках, достаточно будет подавить stdout чтобы только stderr получал вывод на консоль.
Способ сделать это (как в bash и в fish) - добавить >/dev/null к команде. Это выводит stdout в небытие, но stderr (с вашими сообщениями об ошибках) все еще проходит через консоль.
Так, например:
Команда echo 1 >/dev/null ничего не печатает, потому что нормальный вывод stdout подавлен и ничего не записано в stderr.
Команда man doesnotexist >/dev/null печатает сообщение об ошибке, потому что man записывает свое сообщение об ошибке в stderr .
Это запустит команду в фоновом режиме и запишет ошибки в файл журнала, игнорируя при этом нормальный вывод
command > /dev/null 2> /tmp/example_error.log &
