Как подавить вывод команды, но показать ее, если команда выхода кодирует ошибку?
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 &