Еще горстка материалов:

Потоки вывода в Linux

Потоки вывода в Unix (bash/sh)

Сообщения от скриптов и программ выводятся в определенные потоки вывода.

Т.е. написав в терминале echo "I am your PC", результат выводится на экран, но с точки зрения компьютера результат выводится через определенный поток вывода в терминал. В случае echo это поток под номером 1, называется stdout (с ним ассоциирован экран).

Некоторые программы еще используют другой поток вывода с номером 2, который называется stderr. В него они выводятся сообщения об ошибках.

Перенаправим все обычные информационные сообщения команды ls в файл test.file:

$ ls > test.file

Получим таким образом в этом файле ответ команды ls.

При этом мы не увидим ничего на экране, а в файле test.file будет находится все то, что должно было отобразиться на экране.

Теперь сделаем ошибочную команду:

$ ls /hren > test.file

Т.к. директории «hren» в корне файловой системы нет, то команда ls выдаст ошибку. Однако вывалит ее не через обычный поток stdout, а через поток ошибок stderr. А перенаправление задано лишь для stdout.

Теперь выполним команду ls так, чтобы данные записались в файл test.file, а сообщения об ошибках в файл test.stderror, при этом на экране во время выполнения не появится ничего:

$ ls >test.file 2>test.stderror

Запись "2>test.stderror" указывает, что поток с номером 2 (stderr) нужно перенаправить в файл test.stderror.

Иногда встречается запись 2>&1. Она означает, что поток с номером 2 перенаправить в поток с номером 1, т.е. поток stderr - направить через поток stdout. 

$ ls /hren 2>&1

Перенаправим все сообщения в файл test.file:

$ ls /hren >test.file 2>&1

При этом все сообщения, как об ошибках, так и обычные, будут записаны в test.file, т.к. поток stdout мы сначала перенаправили в файл, а потом указали, что ошибки нужно отправить в stdout,т.е. в файл test.file

Иногда появляется необходимость скрыть все выдаваемые сообщения. Для этого можно использовать устройство /dev/null.

Весь вывод обычных сообщений команды ls мы направим в /dev/null:

$ ls > /dev/null

На экране не увидим ничего, кроме сообщений об ошибках.

В этом примере также сообщения об ошибках будут отправлены в девнулл:

$ ls > /dev/null 2>&1

Причем эта запись тоже что и эта:

$ ls >/dev/null 2>/dev/null

А в этом примере уберем только сообщения об ошибках:

$ ls 2>/dev/null

Кстати, здесь уже нельзя указывать "2>&1", т.к. поток stdout не перенаправлен никуда и в таком случае сообщения об ошибках будут выданы на экран.

Еще два примера. Порядок указателей перенаправления играет роль!

Интерпретаторы читают и применяют перенаправления слева направо.

1)

$ ls >/dev/null 2>&1

">/dev/null" - мы направляем поток 1 (stdout) в /dev/null.

"2>&1" - мы перенаправляем поток 2 (stderr) в поток 1 (stdout). Но, т.к. поток 1 уже ассоциирован с /dev/null все сообщения все-равно попадут в /dev/null.

В результате на экране пусто.

2)

$ ls 2>&1 >/dev/null

"2>&1" - мы перенаправляем поток ошибок stderr (2) в поток stdout (1). Но, т.к. поток 1 по-умолчанию ассоциирован с терминалом - сообщения об ошибках мы успешно увидим на экране.

">/dev/null" - а уже здесь мы перенаправляем поток 1 в /dev/null. И обычные сообщения мы не увидим.

В результате мы будем видеть сообщения об ошибках на экране, но не будем видеть обычные сообщения.

 

Обновлено 06.04.2016 07:23

unix-way