{{tag>bash pipe linux pipe}}

===== Перенаправление стандартных потоков ввода вывода =====


Перенаправление обычно осуществляется вставкой специального символа '''>''' между командами. Обычно синтаксис выглядит так:


<code>
команда1 > файл1
</code>


выполняет команду1, помещая стандартный вывод в файл1.
<code>
команда1 < файл1
</code>


выполняет команду1, используя в качестве источника ввода файл1 (вместо клавиатуры).


<code>
команда1 < файл1 > файл2
</code>


совмещает два предыдущих варианта. Выполняет команду1 вводя из файла1 и выводя в файл2
===== Конвейеры =====


''Конвейеры''— это возможность нескольких программ работать совместно, когда выход одной программы непосредственно идет на вход другой без использования промежуточных временных файлов. Синтаксис:


команда1 | команда2


Выполняет команду1 используя её поток вывода как поток ввода при выполнении команды2, что равносильно использованию двух перенаправлений и временного файла:
<code>
команда1 > ВременныйФайл
команда2 < ВременныйФайл
rm ВременныйФайл
</code>


Хороший пример командных конвейеров — это объединение echo с другой командой для получения интерактивности в неинтерактивных средах, к примеру:


echo -e "ИмяПользователя%%\%%nПароль" | ftp localhost


Здесь запускается [[:system:shell:ftp|ftp]] клиент, который подключается к localhost под именем ИмяПользователя, нажимает Enter и затем вводит пароль Пароль.
===== Перенаправление в/из стандартных файловых дескрипторов =====


В командной оболочке UNIX, произошедшей из Bourne shell, предыдущие два действия можно усовершенствовать, указав номер(файловый дескриптор) непосредственно перед символом перенаправления. Этот номер указывает какой именно поток используется для перенаправления. В UNIX существуют следующие стандартные потоки ввода/вывода:


\\ 
^Дескриптор ^Название ^Описание |
|0 |[[http://ru.wikipedia.org/wiki/Stdin|stdin]] |Стандартный ввод |
|1 |[[http://ru.wikipedia.org/wiki/Stdout|stdout]] |Стандартный вывод |
|2 |[[http://ru.wikipedia.org/wiki/Stderr|stderr]] |Стандартный вывод ошибок |
\\ 

К примеру:


<code>
команда1 2 > файл1
</code>


выполняет команду1 направляя стандартный поток ошибок в файл1


В командных оболочках произошедших от C Shell по правилам синтаксиса для указания потока, в который осуществляется перенаправление нужно добавлять символ & после символа перенаправления.


Часто стандартный поток ошибок объединяют со стандартным потоком вывода, чтобы можно было обрабатывать ошибки и обычные результаты работы программы вместе. К примеру:


<code>
find / -name .profile> results.txt 2>&1
</code>


попытается найти все файлы с именем .profile. Если выполнять эту команду без перенаправлений она будет направлять результаты поиска в [[:system:shell:stdout|stdout]], а сообщения об ошибках(к примеру о недостаточности прав доступа при попытке поиска в защищенных директориях) в [[:system:shell:stderr|stderr]]. По умолчанию эти роли выполняет консоль. Если стандартный поток вывода направлен в файл результаты, то ошибки по-прежнему будут направляться в консоль. Чтобы и ошибки и результаты поиска направлялись в файл results.txt стандартные потоки ошибок и вывода были объединены используя **2>&1**.


Написание **2>&1** перед **>** не будет работать, так как когда интерпретатор прочитает **2>&1**, он ещё не знает куда перенаправлен стандартный поток вывода, поэтому потоки ошибок и вывода не будут объединены.


Если объединенный результат нужно направить на вход другой программы посредством конвейера, тогда последовательность **2>&1** должна стоять перед знаком конвейера. К примеру:
<code>
find / -name .profile 2>&1 | less
</code>


Упрощенная форма записи команды:


<code>
команда> файл 2>&1
</code>


выглядит так:


<code>
команда &> файл
</code>


или


<code>
команда>& файл
</code>


===== Цепочка конвейеров =====


Команды перенаправления и конвейеризации могут быть объединены в цепочки для получения более сложных команд, к примеру:


<code>
ls | grep '.sh' | sort> shlist
</code>


Получает список содержимого текущей директории, который фильтруется, оставляя только строки содержащие <tt>'.sh'</tt>, затем этот отфильтрованный список лексически сортируется и окончательный результат помещается в файл <tt>shlist</tt>. Конструкции подобного типа часто встречаются в скриптах командной оболочки UNIX.


===== Перенаправление в несколько выводов =====


Стандартная команда **[[:system:shell:tee|tee]]** может перенаправить вывод команды в несколько мест одновременно. Пример:
<code>
ls -lrt | tee файл1
</code>


направляет стандартный вывод команды **ls -lrt** (список файлов) как в консоль так и в **файл1**.
===== Перенаправление с добавлением =====


В командной оболочке [[:system:shell:bash|Bash]] можно осуществить перенаправление в файл с добавлением в конец. При этом информация, хранящаяся в файле не будет удалена, а вся новая информация будет добавлена в конец этого файла. Синтаксис:


<code>
команда1>> файл1
</code>


===== Встроенный документ =====


Некоторые оболочки, и даже прикладные ЯВУ (PHP], Perl) допускают синтаксис встроенных документов (см. Heredoc-синтаксис), позволяющий направлять входной поток из самого файла программы, например:  cat<<EOF  Здесь помещается произвольный текст,  в том числе включающий в себя специальные символы  EOF

Завершающая сигнатура окончания встроенного документа EOF (можно использовать произвольное значение, но часто используется именно EOF - соответственно смыслу) должна начинаться с начала строки.
