В самом начале хочу отметить, что интерпретатор работает с тремя стандартными потоками:
- stdout это стандартный поток вывода, который обеспечивает вывод команды. Дескриптор потока равен 1.
- stderr это стандартный поток ошибок, который выводит ошибки команд. Его дескриптор равен 2.
- stdin это стандартный поток ввода, который обеспечивает ввод командам. Его дескриптор равен 0.
Теперь простыми словами опишем, что эти три пункта обозначают:
stdout - стандартный поток вывода. Это, говоря простым языком, та информация, которую мы видим в интерпретаторе при выполнении команд. То есть все сообщения (без сообщений об ошибках), которые выполняемая в интерпретаторе команда сообщает и выводит на терминал (читай - экран). (вывод на экран задан по умолчанию, но можно указать и вывод, например в файл или перенаправление в другую команду, как это делается, расскажу ниже)
stderr - поток ошибок. Это ошибки при выполнении команд в bash, которые по умолчанию выводятся на stdout, то есть на терминал (опять же, если не указан вывод в другое место)
stdin - поток ввода. Это, говоря простым языком - то, что мы вводим с клавиатуры в интерпретатор для выполнения команды.
Очень хорошо данные потоки изображены на рисунке, взятом с http://rus-linux.net/:
На данном изображении: Stdin, показан зеленым, имеет дескриптор 0
Stdout, показан красным, имеет дескриптор 1
Stderr, показан синим, имеет дескриптор 2
Stdout, показан красным, имеет дескриптор 1
Stderr, показан синим, имеет дескриптор 2
Далее расскажу, как данные потоки можно перенаправить в/из файл. То есть при выполнении команды, чтобы сообщения или ошибки выводились не на экран, а записывались в файл. Для чего это нужно? Ну например вы выполняете какую-то команду, у которой вывод не помещается в окно терминала. Вы указываете сохранять стандартный вывод в один файл, а стандартный поток ошибок в другой. Тем самым, все ошибки и если нужно стандартный вывод, можно будет посмотреть подробно, открыв сохраненные файлы.
Итак, перенаправление потоков выполняется следующим образом:
$ command n>file
В данной строке показано: выполнение команды command и перенаправление потока (где n = дескриптору потока) в файл file.При выполнении данного перенаправления, если конечный файл существует, он будет перезаписан. При этом, если n не указан, то предполагается стандартный вывод.
$ command n>>file
Данная команда имеет аналогичный синтаксис, но тут указан символ ">>". При данном перенаправлении, если конечный файл существует, то вывод команды будет добавлен к имеющимся данным.
$ command < file
в данном примере команда command выполняется и использует в качестве источника ввода, файл file, вместо ввода с клавиатуры
Иногда возникает необходимость объединить стандартный поток ошибок со стандартным потоком вывода, чтобы можно было обрабатывать ошибки и обычные результаты работы программы вместе. для этих целей используется комбинация с символом: &. Пример выполнения данного действия:
find / -name .name_file > /path/to/file 2>&1
При выполнении данной команды, происходит поиск файла от корня файловой системы с именем .name_file и перенаправление результатов поиска (stdout и stderr) в файл /path/to/file. Конструкция > /path/to/file 2>&1 перенаправляет стандартный вывод в/path/to/file и вывод ошибок в стандартный вывод. При этом: написание 2>&1 перед > не будет работать, так как когда интерпретатор прочитает 2>&1, он еще не знает куда перенаправлен стандартный поток вывода, поэтому потоки ошибок и вывода не будут объединены.
$ command > file 2>&1
аналогична написанию:
$ command &> file
или:
$ command 2>&file
Если необходимо проигнорировать вывод, его можно направить в устройство /dev/null, это своего рода "черная дыра", принимающая любое количество информации и превращающая ее в ничто.
Думаю приведенной информации о перенаправлении потоко будет достаточно для понимания сути, теперь расскажу о конвеерной передаче.
Конвеер в Linux - это возможность нескольких программ работать совместно, когда выход одной программы непосредственно передается на вход другой без использования промежуточных временных файлов. Синтаксис использования конвеера следующий:
$ command1 | command2
В данном примере выполняется команда command1, ее поток вывода используется, как поток ввода при выполнении command2 .