Назад | Перейти на главную страницу

Linux Pipe, предупреждающие сообщения, стандартный вывод

Это, вероятно, лучшее место, чтобы задать вопрос в его простейшей форме. Я пишу сценарий, который принимает выходные данные команды и помещает их в переменную. После некоторой отладки я понял, что команда, когда она ошибается, переходит не в стандартный вывод, а на консоль (или стену). См. Пример ниже:

Когда команда выполняется успешно

root@local# apcaccess status
APC : 700
VERSION : xxxxx
BATTSTAT : AC

Когда команда выдает ошибку

root@local# apcaccess status
apcupsd @ localhost: Connection Refused.

root@local# apcaccess status | grep -i version
apcupsd @ localhost: Connection Refused.

Я заметил, когда пытаюсь передать команду через grep 'apcaccess status | grep -i version 'Я получу номер версии при успешном запуске, но в системе, в которой произошла ошибка, я получаю сообщение об ошибке. Я считаю, что это не проходит через стандартный вывод.

Возникает вопрос: как заставить вывод перейти на стандартный вывод?

# apcaccess status 2>&1 | grep -i version

Это перенаправит stderr на stdout, поэтому grep увидит результат.

Причина в том, что на самом деле открыто два файловых дескриптора, которые «выводят» на ваш экран. stdout (представленный дескриптором файла 1) и stderr (дескриптор файла 2). Когда вы передаете одну команду другой, вы просто берете стандартный вывод из первой команды и «перенаправляете» его как стандартный ввод второй команде. Но если первая команда что-то напечатала в stderr (обычно это сообщение об ошибке), то это не передается через конвейер, а выводится прямо на ваш экран.

Итак, вам нужно перенаправить stderr на stdout. Достигнуто следующим образом.

command1 2> & 1 | command2

Подсказки: Причина, по которой амперсанд необходим, заключается в том, что вам нужно сказать, что вы перенаправляете stderr (2) в дескриптор файла стандартный вывод (1). В противном случае без амперсанда вы просто говорите stderr перенаправить на файл с именем «1» в текущем рабочем каталоге. Подобно тому, что вы могли бы сделать, когда вы сбрасываете «вывод» команды (stdout) в файл через 'command> myfile.log'. Отсутствие файлового дескриптора перед командой перенаправления по умолчанию равно 1 (stdout).