Как запустить команду в фоновом режиме без вывода, если нет ошибки

Как подавить вывод команды, но показать ее, если команда выхода кодирует ошибку?

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 &
Другие вопросы по тегам