Сегодня вечером я возился со своей сетевой картой, когда заметил что-то, когда запускаю ip link help . Вот два случая, когда я заметил что-то другое:

ip link help | grep set

а также

ip link help > ip_link_help.txt

Первая команда не имеет никакого эффекта, то есть вместо перенаправления вывода ip link help из stdout в grep , канал просто игнорируется, а вывод ip link help отправляется в stdout .

Второй случай немного другой. Хотя ip link help игнорирует символ перенаправления > и просто печатает на стандартный stdout , файл file.txt все равно создается (но он пуст).

1 ответ1

3

ip link help выводит на стандартную ошибку (stderr, дескриптор файла 2); его стандартный вывод (stdout, дескриптор файла 1) не получает данных. Обычно два потока идут к терминалу, так что вы не можете различить их на первый взгляд. | или > влияет на стандартный вывод. После его использования вы знаете, что любые данные, которые будут перенаправлены, должны быть направлены в stdout; все остальное - в другое место: обычно в stderr, хотя некоторые программы печатают некоторые данные непосредственно в терминал (ip не является одним из них).

В первом случае вы можете перенаправить stderr в файловый дескриптор stdout, а затем построить конвейер:

ip link help 2>&1 | grep set

где 2>&1 указывает оболочке перенаправить файловый дескриптор 2 на любой файловый дескриптор 1 указывает. С этим синтаксисом, если команда выведет что-то в stdout и stderr, все получится в grep .

Во втором случае оболочка создает (при необходимости) и усекает файл перед запуском ip . Вы можете увидеть это, вызвав

a_command_that_doesnt_even_exist > foo.txt

foo.txt будет создан, несмотря на очевидную ошибку. Это потому, что он создается первым, еще до того, как оболочка попытается запустить команду.

Для захвата stderr в файл используйте 2> который перенаправляет только stderr:

ip link help 2> ip_link_help.txt

Аналогично 1> перенаправляет только стандартный вывод. Short > вы использовали строго эквивалентно 1> .


Искусственный пример команды, которая печатает на терминал тремя различными способами:

echo "standard output"; echo "standard error" >&2; echo "terminal" >/dev/tty

Выход:

standard output
standard error
terminal

Вы можете легко перенаправить первые две строки. Попробуй это:

(echo "standard output"; echo "standard error" >&2; echo "terminal" >/dev/tty) >stdout.txt 2>stderr.txt

Это все равно будет печатать последнюю строку.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .