Библиотека сайта 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. Фильтры |