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

Хорошая статья о перенаправлении стандартных потоков. Мы часто используем это, когда набираем составные команды в консоли, но зачастую делаем это несознательно или просто взяли с конвейр с какой нибудь статьи и не даже не задумываемся как это работает. Вообщем рекомендую к прочтению.

 

взято с http://rus-linux.net/lib.php?name=MyLDP%2Fconsol%2FHuMan%2Fredirection-ru.html

Введение

Прежде чем заводить речь о перенаправлениях, нужно представлять себе работу процесса в Юниксовидных ОС. Вдаваться во внутреннюю структуру процесса не входит в наши намерения, мы будем рассматривать процесс как некий «черный ящик», а лучше завод, перерабатывающий данные.

Наблюдая за заводом извне, мы замечаем три потока:

 

  • 0. На территорию завода поступает входящий поток «сырья» — данных подлежащих переработке.
  •  

  • 1. Из ворот выходит поток продукции — данных, подвергшихся переработке на заводе-процессе.
  •  

  • 2. Из трубы поднимается дым, по виду которого можно судить о работе завода. Если дыма не заметно, то завод работает нормально (у нас ведь экологически чистое производство информации). Если вдруг повалил густой дым, то, ясное дело, что-то не в порядке.

На компьютерном языке эти три потока данных называются стандартными потоками. Каждый имеет числовой дескриптор (номер), название и направление по умолчанию.

Дескриптор 0: Входящий стандартный поток (Standart Input, stdin). По умолчанию, поступает со стандартного устройства ввода (обычно с клавиатуры).

Дескриптор 1: Выходящий стандартный поток (Standar Output, stdout). По умолчанию направляется на стандартное устройство вывода (обычно экран монитора).

Дескриптор 2: Стандартный поток сообщений об ошибках (Standart Error, stderr). С английского переводится как «стандартная ошибка», но в русском языке такое выражение звучит двусмысленно. Поэтому я предпочитаю называть его стандартным сообщением, тем более, что в большинстве случаев оно сообщает не об ошибке, а о ходе процесса. По умолчанию направляется туда же, куда и стандартный вывод — на экран монитора, но не смешивается со стандартным выводом, а раскладывается по разным «полкам».

 

mill
Входящий поток, показан зеленым, имеет дескриптор 0
Выходящий поток, показан красным, имеет дескриптор 1
Поток сообщений, показан синим, имеет дескриптор 2

Вот пример стандартного ввода и вывода:

$ echo стандарный ввод   (Enter)

стандарный ввод

Команда echo направляет поток данных с клавиатуры на экран дисплея.

А вот пример стандартного сообщения об ошибке:

 

$ cat file.txt

cat: file.txt: Нет такого файла или каталога

Каждый из этих стандартных потоков можно перенаправлять, то есть направлять не туда, куда поток направляется по умолчанию. Это и есть перенаправление.

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

Во многих случаях удобнее работать не со стандартным выводом на монитор, а с файлами. Файлы можно сохранять, редактировать, посылать по почте, и т.д. Мы всегда можем перенаправить вывод команды в файл, применив оператор перенаправления > и указав имя файла. При этом не важно, существует ли такой файл на самом деле. Если такого файла нет, то он будет создан, а если есть, то перезаписан (все прежнее содержимое будет стерто, а новое записано).

 

$ echo стандарный ввод > ввод.txt

Как видите, на экране не появились слова «стандартный ввод», зато в текущей директории появился файл ввод.txt с этими словами.

Можно дописать в файл ввод.txt вывод других команд, не уничтожая имеющегося содержимого. Для этого служит оператор >>

 

$ echo и стандарный вывод >> ввод.txt

Проделайте этот опыт самостоятельно, чтобы убедиться, что это так. Для определения текущей директории применяется команда pwd:

 

$ pwd

/home/ваш_логин/

Это я на случай, если вы не сразу найдете файл ввод.txt. (pwd расшифровывается как «print working directory» — «сообщить рабочую директорию»).

Внимание: Следите за тем, в какой директории вы находитесь и без надобности не перенаправляйте вывод в существующие файлы. Могут быть уничтожены важные файлы (особенно, если вы имеете дурную привычку работать под логином администратора — root’а).

Перенаправление ввода

Не все команды принимают файлы в качестве аргумента; некоторые принимают данные только из стандартного ввода.

Например, команда tr, которая служит для перевода (замены) выбранных символов в другие символы или удаления их.

На этот случай служит оператор перенаправления ввода < .

 

$ tr [a-z] [A-Z] < case.txt

TRANSLATION LOWER
CASE INTO UPPERCASE

В файле case.txt содержался тот же текст, только написанный строчными буквами.

Если желательно записать результат работы команды в другой файл, то можно совместить перенаправление ввода с перенаправлением вывода:

 

$ tr [a-z] [A-Z] < case.txt > case-upper.txt

Появится файл case-upper.txt, содержащий только что виденный нами текст.

И, наконец, можно дописать изменения текста в исходный файл:

 

$ tr [a-z] [A-Z] < case.txt >> case.txt

А вот пытаться переписать исходный файл измененным текстом не получится — будут утеряны и исходный файл и результат изменений:

 

$ tr [a-z] [A-Z] < case.txt > case.txt

Попробуйте сами…

Перенаправление стандартного потока сообщений

Если команда «страдает болтливостью», то есть выводит множество сообщений, которые вам не нужны, или непонятны, то лучше перенаправить поток этих сообщений в другое русло. Вывод ненужных сообщений замедляет работу команды, засоряет экран монитора, отвлекает от работы.

Например, команда wc, которая подсчитывает количество строк, слов, байт, или символов, работает только с текстовыми файлами (кроме опции -с). Если среди заданных команде для обработки файлов попадутся бинарные или .html файлы, то команда выдаст множество сообщений. Зададим команде wc просчитать все файлы в текущей директории (при помощи символа астериска — *)

 

$ wc *

wc: Documents: Is a directory
0 0 0 Documents
9 14 207 MyComputer.desktop
310 1963 12555 bookindx.txt
2 5 39 case-upper.txt
2 5 38 case.txt
wc: mill.gif:1: Invalid or incomplete multibyte or wide character
wc: mill.gif:2: Invalid or incomplete multibyte or wide character
wc: mill.gif:3: Invalid or incomplete multibyte or wide character
wc: mill.gif:4: Invalid or incomplete multibyte or wide character
wc: mill.gif:5: Invalid or incomplete multibyte or wide character
wc: mill.gif:6: Invalid or incomplete multibyte or wide character
73 307 12702 mill.gif
119 745 9468 redirections_and_pipes.txt
wc: sed.html:53: Invalid or incomplete multibyte or wide character

2732 14592 167105 sed.html
682 4198 29314 sed_mcmahon.txt
114 156 1715 shema.txt
150 318 5066 trash.desktop
15 18 258 Дисковод
1 0 2 Текстовый файл
4209 22321 238469 итого

Строки вывода, начинающиеся с wc: являются сообщениями. На самом деле этих сообщений было намного больше, мне пришлось уменьшить их количество, чтобы не загромождать статью.

Избавиться от них очень просто: нужно воспользоваться тем же оператором перенаправления (>), предварив его номером перенаправляемого потока. Стандартный поток сообщений имеет дескриптор (номер) 2, вот и поставим двойку перед оператором перенаправления — 2> . Куда же перенаправить этот поток? Можно перенаправить в какой-нибудь файл, если хотите на досуге разобраться с этими сообщениями. (Например, при компиляции программ выдается множество сообщений, которые вовсе не бессмысленны). А если сообщения вам не нужны, то лучше перенаправить их в файл /dev/null. Это специальный файл, который принимает любое количество данных и обращает их в ничто — эдакая бездонная и безвозвратная мусорная корзина, а лучше — «черная дыра». Вот в нее то и направим ненужный поток сообщений:

 

$ wc * 2> /dev/null
0 0 0 Documents
9 14 207 MyComputer.desktop
310 1963 12555 bookindx.txt
2 5 39 case-upper.txt
2 5 38 case.txt
73 307 12702 mill.gif
119 745 9468 redirections_and_pipes.txt
2732 14592 167105 sed.html
682 4198 29314 sed_mcmahon.txt
114 156 1715 shema.txt
150 318 5066 trash.desktop
15 18 258 Дисковод
1 0 2 Текстовый файл
4209 22321 238469 итого

В итоге получаем на экране только вывод программы.

Возникает резонный вопрос: «А можно ли прочитать на экране только сообщения, а вывод программы перенаправить в файл?». Конечно можно:

 

$ wc * 1> /dev/null

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

 

$ wc * > /dev/null

wc: Documents: Is a directory
wc: mill.gif:1: Invalid or incomplete multibyte or wide character
wc: mill.gif:2: Invalid or incomplete multibyte or wide character
wc: mill.gif:3: Invalid or incomplete multibyte or wide character
...

Существует также возможность перенаправить потоки 1 и 2 в разные файлы:

 

$ wc * > wc.txt 2> /dev/null

Убедитесь сами, что файл wc.txt не содержит стандартных сообщений.

И последняя хитрость. Можно направить оба выходных потока: стандарный вывод и стандартное сообщение в один и тот же файл, так, чтобы в файле сохранить все, что мы увидели бы на экране монитора:

 

$ wc * > wc.txt 2>&1

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

Заключение

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

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

Войти с помощью: