Библиотека сайта rus-linux.net
Фундаментальные основы Linux. Часть IV. Программные каналы и команды
Оригинал: Linux Fundamentals
Автор: Paul Cobbaut
Дата публикации: 16 октября 2014 г.
Перевод: А.Панин
Дата перевода: 15 декабря 2014 г.
Глава 16. Перенаправление потоков ввода/вывода
Одной из мощных возможностей командной оболочки системы Unix является механизм перенаправления потоков ввода/вывода с возможностью задействования программных каналов.
В данной главе даются пояснения относительно перенаправления стандартных потоков ввода, вывода и ошибок.
Потоки данных stdin, stdout и stderr
Командная оболочка bash поддерживает три типа базовых потоков данных; она принимает данные из стандартного потока ввода stdin (поток 0), отправляет данные в стандартный поток вывода stdout (поток 1), а также отправляет сообщения об ошибках в стандартный поток ошибок stderr (поток 2).
Приведенная ниже иллюстрация является графической интерпретацией этих трех потоков данных.
Клавиатура обычно служит источником данных для стандартного потока ввода stdin, в то время, как стандартные потоки вывода stdout и ошибок stderr используются для вывода данных. Новых пользователей Linux может смущать подобное разделение, так как не существует очевидного способа дифференцирования стандартных потоков вывода stdout и ошибок stderr. Опытные же пользователи знают о том, что разделение стандартных потоков вывода и ошибок может оказаться весьма полезным.
В следующем разделе будет рассказано о том, как осуществляется перенаправление упомянутых потоков данных.
Перенаправление стандартного потока вывода
Операция перенаправления потока данных stdout (>)
Перенаправление стандартного потока вывода stdout может быть осуществлено с помощью символа знака "больше". В том случае, если при разборе строки команды командная оболочка обнаруживает символ знака >, она удаляет данные из файла и перенаправлет данные из стандартного потока вывода в него.
> фактически является аббревиатурой для 1> (в данном случае стандартный поток вывода обозначается как поток номер 1).
[paul@RHELv4u3 ~]$ echo Сегодня холодно! Сегодня холодно! [paul@RHELv4u3 ~]$ echo Сегодня холодно! > winter.txt [paul@RHELv4u3 ~]$ cat winter.txt Сегодня холодно! [paul@RHELv4u3 ~]$
удаляет описание операции перенаправления потока данных из строки команды перед исполнением этой команды, представленной аргументом 0. Это значит, что в случае исполнения данной команды:
echo привет > greetings.txt
командная оболочка будет рассматривать только два аргумента (echo = аргумент 0, привет = аргумент 1). Описание операции перенаправления потока данных удаляется перед началом подсчета количества аргументов.
Содержимое выходного файла удаляется
содержимое указанного после него файла будет удалено! Ввиду того, что описанная процедура выполняется перед извлечением аргумента 0, содержимое файла будет удалено даже в случае неудачного исполнения команды!
[paul@RHELv4u3 ~]$ cat winter.txt Сегодня холодно! [paul@RHELv4u3 ~]$ zcho Сегодня холодно! > winter.txt -bash: zcho: команда не найдена.. [paul@RHELv4u3 ~]$ cat winter.txt [paul@RHELv4u3 ~]$
Параметр командной оболочки noclobber
> может быть предотвращено путем установки параметра командной оболочки noclobber.
[paul@RHELv4u3 ~]$ cat winter.txt Сегодня холодно! [paul@RHELv4u3 ~]$ set -o noclobber [paul@RHELv4u3 ~]$ echo Сегодня холодно! > winter.txt -bash: winter.txt: не могу переписать уже существующий файл [paul@RHELv4u3 ~]$ set +o noclobber [paul@RHELv4u3 ~]$
Нейтрализация влияния параметра командной оболочки noclobber
noclobber может быть нейтрализовано с помощью оператора >|.
[paul@RHELv4u3 ~]$ set -o noclobber [paul@RHELv4u3 ~]$ echo Сегодня холодно! > winter.txt -bash: winter.txt: не могу переписать уже существующий файл [paul@RHELv4u3 ~]$ echo Сегодня очень холодно! >| winter.txt [paul@RHELv4u3 ~]$ cat winter.txt Сегодня очень холодно! [paul@RHELv4u3 ~]$
Оператор дополнения >>
>> для записи данных из стандартного потока вывода в конец файла без предварительного удаления содержимого этого файла.
[paul@RHELv4u3 ~]$ echo Сегодня холодно! > winter.txt [paul@RHELv4u3 ~]$ cat winter.txt Сегодня холодно! [paul@RHELv4u3 ~]$ echo Когда же наступит лето ? >> winter.txt [paul@RHELv4u3 ~]$ cat winter.txt Сегодня холодно! Когда же наступит лето ? [paul@RHELv4u3 ~]$
Перенаправление стандартного потока ошибок
Операция перенаправления потока данных stderr (2>)
Перенаправление стандартного потока ошибок осуществляется с помощью оператора 2>. Такое перенаправление может оказаться очень полезным для предотвращения заполнения вашего экрана сообщениями об ошибках.
стандартного потока вывода в файл, а данных из стандартного потока ошибок - в специальный файл устройства /dev/null. Запись 1> идентична записи >.
[paul@RHELv4u3 ~]$ find / > allfiles.txt 2> /dev/null [paul@RHELv4u3 ~]$
Операция перенаправления нескольких потоков данных 2>&1
стандартного потока вывода, так и из стандартного потока ошибок в один и тот же файл следует использовать конструкцию 2>&1.
[paul@RHELv4u3 ~]$ find / > allfiles_and_errors.txt 2>&1 [paul@RHELv4u3 ~]$
ls > dirlist 2>&1
ls 2>&1 > dirlist
позволяет перенаправить только данные из стандартного потока вывода в файл dirlist, так как с помощью данной команды осуществляется копирование дескриптора стандартного потока вывода в дескриптор стандартного потока ошибок перед тем, как стандартный поток вывода перенаправляется в файл dirlist.
Перенаправление стандартного потока вывода и программные каналы
стандартного потока ошибок stderr приложения при использовании программных каналов в рамках строки команды, так как данная утилита получает данные исключительно из стандартного потока вывода stdout приложения.
paul@debian7:~$ rm file42 file33 file1201 | grep file42 rm: невозможно удалить "file42": Нет такого файла или каталога rm: невозможно удалить "file33": Нет такого файла или каталога rm: невозможно удалить "file1201": Нет такого файла или каталога
2>&1 вы можете переправить данные из стандартного потока ошибок stderr в стандартный поток вывода stdout приложения. Это обстоятельство позволяет обрабатывать передаваемые посредством программного канала данные из обоих потоков с помощью следующей команды.
paul@debian7:~$ rm file42 file33 file1201 2>&1 | grep file42 rm: невозможно удалить "file42": Нет такого файла или каталога
1>&2 и 2>&1 для осуществления обмена файловых дескрипторов между стандартным потоком вывода stdout и стандартным потоком ошибок stderr.
paul@debian7:~$ rm file42 file33 file1201 2>&1 1>&2 | grep file42 rm: невозможно удалить "file42": Нет такого файла или каталога paul@debian7:~$ echo file42 2>&1 1>&2 | sed 's/file42/FILE42/' FILE42
paul@debian7:~$ echo file42 3>&1 1>&2 2>&3 | sed 's/file42/FILE42/' file42 paul@debian7:~$ rm file42 3>&1 1>&2 2>&3 | sed 's/file42/FILE42/' rm: невозможно удалить "FILE42": Нет такого файла или каталога
Объединение стандартных потоков вывода stdout и ошибок stderr
&> позволяет объединить стандартные потоки вывода stdout и ошибок stderr в рамках одного потока данных (причем данные будут сохраняться в файле).
paul@debian7:~$ rm file42 &> out_and_err paul@debian7:~$ cat out_and_err rm: невозможно удалить "file42": Нет такого файла или каталога paul@debian7:~$ echo file42 &> out_and_err paul@debian7:~$ cat out_and_err file42 paul@debian7:~$
Перенаправление стандартного потока ввода
Операция перенаправления потока данных stdin (<)
стандартного потока ввода stdin осуществляется с помощью оператора < (являющегося краткой версией оператора 0<).
[paul@RHEL4b ~]$ cat < text.txt one two [paul@RHEL4b ~]$ tr 'onetw' 'ONEZZ' < text.txt ONE ZZO [paul@RHEL4b ~]$
Структура < here document
here document (иногда называемая структурой here-is-document) является механизмом для ввода данных до момента обнаружения определенной последовательности символов (обычно EOF). Маркер EOF может быть либо введен вручную, либо вставлен автоматически при нажатии комбинации клавиш Ctrl-D.
[paul@RHEL4b ~]$ cat <EOF > text.txt > один > два > EOF [paul@RHEL4b ~]$ cat text.txt один два [paul@RHEL4b ~]$ cat <brol > text.txt > brel > brol [paul@RHEL4b ~]$ cat text.txt brel [paul@RHEL4b ~]$
Структура < here string
here string может использоваться для непосредственной передачи строк команде. При использовании данной структуры достигается такой же эффект, как и при использовании команды echo строка | команда (но вы сможете избежать создания одного дополнительного процесса).
paul@ubu1110~$ base64 < linux-training.be bGludXgtdHJhaW5pbmcuYmUK paul@ubu1110~$ base64 -d << bGludXgtdHJhaW5pbmcuYmUK linux-training.be
Для получения дополнительной информации об алгоритме base64 следует обратиться к стандарту rfc 3548.
Неоднозначное перенаправление потоков ввода/вывода
cat winter.txt > snow.txt 2> errors.txt
2> errors.txt cat winter.txt > snow.txt
< winter.txt > snow.txt 2> errors.txt cat
Быстрая очистка содержимого файла
>foo
noclobber?
>|bar
Практическое задание: перенаправление потоков ввода/вывода
-
1. Активируйте параметр командной оболочки
noclobber. -
2. Проверьте, активирован ли параметр
noclobber, повторив вызов команды вывода содержимого директорииlsдля директории/etcс перенаправлением данных из стандартного потока вывода в файл. -
3. Какой из символов представляет параметр
noclobberв списке всех параметров командной оболочки. -
4. Деактивируйте параметр
noclobber. -
5. Убедитесь в том, что вы имеете доступ к двум командным оболочкам, открытым на одном компьютере. Создайте пустой файл
tailing.txt. После этого выполните командуtail -f tailing.txt. Используйте вторую командную оболочку длядобавлениястроки текста в этот файл. Убедитесь в том, что эта строка была выведена в первой командной оболочке. -
6. Создайте файл, содержащий имена пяти людей. Используйте команду
catи механизм перенаправления потоков ввода/вывода для создания файла, а также структуруhere documentдля завершения ввода.
Корректная процедура выполнения практического задания: перенаправление потоков ввода/вывода
-
1. Активируйте параметр командной оболочки
noclobber. -
set -o noclobber set -C
-
2. Проверьте, активирован ли параметр
noclobber, повторив вызов команды вывода содержимого директорииlsдля директории/etcс перенаправлением данных из стандартного потока вывода в файл. -
ls /etc > etc.txt ls /etc > etc.txt (команда не должна работать)
-
3. Какой из символов представляет параметр
noclobberв списке всех параметров командной оболочки. -
echo $- (параметр noclobber представлен символом C)
-
4. Деактивируйте параметр
noclobber. -
set +o noclobber
-
5. Убедитесь в том, что вы имеете доступ к двум командным оболочкам, открытым на одном компьютере. Создайте пустой файл
tailing.txt. После этого выполните командуtail -f tailing.txt. Используйте вторую командную оболочку длядобавлениястроки текста в этот файл. Убедитесь в том, что эта строка была выведена в первой командной оболочке. -
paul@deb503:~$ > tailing.txt paul@deb503:~$ tail -f tailing.txt hello world в другой командной оболочке: paul@deb503:~$ echo hello >> tailing.txt paul@deb503:~$ echo world >> tailing.txt
-
6. Создайте файл, содержащий имена пяти людей. Используйте команду
catи механизм перенаправления потоков ввода/вывода для создания файла, а также структуруhere documentдля завершения ввода. -
paul@deb503:~$ cat > tennis.txt < ace > Justine Henin > Venus Williams > Serena Williams > Martina Hingis > Kim Clijsters > ace paul@deb503:~$ cat tennis.txt Justine Henin Venus Williams Serena Williams Martina Hingis Kim Clijsters paul@deb503:~$
| Предыдущий раздел: | Оглавление | Следующий раздел: |
| Глава 15. Формирование списков имен файлов на основе шаблонов | Глава 17. Фильтры |
