Перенаправление потоков

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

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

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

команда1 > файл1

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

команда1 < файл1

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

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

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

Перенаправление с добавлением

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

команда1 >> файл1

Перенаправление в/из стандартных файловых дескрипторов

В UNIX существуют следующие стандартные потоки ввода-вывода:

Дескриптор Название Описание
0 stdin Стандартный ввод
1 stdout Стандартный вывод
2 stderr Стандартный вывод ошибок

К примеру:

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

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

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

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

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

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

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

Если объединенный результат нужно направить на вход другой программы посредством конвейера, тогда последовательность 2>&1 должна стоять перед знаком конвейера. К примеру:

find / -name .profile 2>&1 | less

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

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

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

команда &> файл

или

команда >& файл

Оболочка, при разборе параметров командной строки, читает параметры строго слева направо. Этот факт кажется совсем неудивительным, но именно это правило оказывает влияние на результат обработки командной строки.

Разберем, как интерпретируется строка:

ls *.txt *.err >file 2>&1
  1. параметр ">file" — означает "перенаправить стандартный поток вывода (stdout) в файл c именем file";
  2. параметр "2>&1" — означает "перенаправить стандартный поток ошибок (2) в стандартный поток вывода (1). Но, так как стандартный поток вывода уже перенаправлен в файл, то и стандартный поток ошибок перенаправляется туда же.

В результате оба потока будут перенаправлены в файл.

А как интерпретируется строка:

ls *.txt *.err 2>&1 >file
  1. параметр "2>&1" — означает "перенаправить стандартный поток ошибок в стандартный поток вывода". На этот момент поток вывода (1) направляется в терминал, а значит, что поток ошибок тоже перенаправится в терминал.
  2. параметр ">file" — означает "перенаправить стандартный поток вывода (stdout) в файл c именем file".

Как результат — поток вывода будет направлен в файл, а поток ошибок — в терминал.

После этого совсем не трудно понять, как работает команда

cat file 3>&2 2>&1 1>&3

Тут тоже все просто:

  1. поток вывода 3 перенаправить туда же, куда выводится поток вывода 2 — в stderr;
  2. поток вывода 2 перенаправить туда же, куда выводится поток 1 — в stdout;
  3. поток вывода 1 перенаправить туда же, куда выводится поток 3 — в stderr

В результате, потоки вывода stderr и stdout как будто меняются местами — поток 1 идет в stderr, а поток 2 идет в stdout.

Конвейеры

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

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

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

команда1 > ВременныйФайл
команда2 < ВременныйФайл
rm ВременныйФайл

Пример скрипта на ввод учетных данных к FTP:

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

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

Здесь запускается ftp клиент, который подключается к localhost под именем ИмяПользователя, нажимает Enter и затем вводит пароль Пароль.

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

Стандартная команда tee может перенаправить вывод команды в несколько мест одновременно.
Пример:

ls -lrt | tee файл1

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

Источники:
http://ru.wikipedia.org/wiki/Перенаправление_ввода-вывода
http://white-knight-is-alive.blogspot.ru/2006/05/2.html

Метки: . Закладка Постоянная ссылка.

Добавить комментарий

Ваш e-mail не будет опубликован.

*