- Перенаправление стандартных потоков линукс
- Потоки данных stdin, stdout и stderr
- Перенаправление стандартного потока вывода
- Перенаправление стандартного потока ошибок
- Перенаправление стандартного потока вывода и программные каналы
- Объединение стандартных потоков вывода stdout и ошибок stderr
- Перенаправление стандартного потока ввода
- Неоднозначное перенаправление потоков ввода/вывода
- Быстрая очистка содержимого файла
- Практическое задание: перенаправление потоков ввода/вывода
- Корректная процедура выполнения практического задания: перенаправление потоков ввода/вывода
Перенаправление стандартных потоков линукс
В данной главе даются пояснения относительно перенаправления стандартных потоков ввода, вывода и ошибок.
Потоки данных 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 ~]$
Обратите внимание на то, что командная оболочка bash фактически удаляет описание операции перенаправления потока данных из строки команды перед исполнением этой команды, представленной аргументом 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
[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 ~]$
Помните о том, что последовательность операций перенаправления потоков данных имеет значение. К примеру, команда
позволяет перенаправить как данные из стандартного потока вывода (с файловым дескриптором 1), так и данные из стандартного потока ошибок (с файловым дескриптором 2) в файл dirlist, в то время, как команда
позволяет перенаправить только данные из стандартного потока вывода в файл dirlist, так как с помощью данной команды осуществляется копирование дескриптора стандартного потока вывода в дескриптор стандартного потока ошибок перед тем, как стандартный поток вывода перенаправляется в файл dirlist.
Перенаправление стандартного потока вывода и программные каналы
По умолчанию вы не можете использовать утилиту grep для обработки данных стандартного потока ошибок 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
Вам потребуется третий поток данных для осуществления обмена файловых дескрипторов между стандартным потоком вывода stdout и стандартным потоком ошибок stderr перед символом для создания программного канала.
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<).
Структура here document (иногда называемая структурой here-is-document) является механизмом для ввода данных до момента обнаружения определенной последовательности символов (обычно EOF). Маркер EOF может быть либо введен вручную, либо вставлен автоматически при нажатии комбинации клавиш Ctrl-D.
[paul@RHEL4b ~]$ cat text.txt > один > два > EOF [paul@RHEL4b ~]$ cat text.txt один два [paul@RHEL4b ~]$ cat text.txt > brel > brol [paul@RHEL4b ~]$ cat text.txt brel [paul@RHEL4b ~]$
Структура here string может использоваться для непосредственной передачи строк команде. При использовании данной структуры достигается такой же эффект, как и при использовании команды echo строка | команда (но вы сможете избежать создания одного дополнительного процесса).
Для получения дополнительной информации об алгоритме base64 следует обратиться к стандарту rfc 3548.
Неоднозначное перенаправление потоков ввода/вывода
Командная оболочка будет осуществлять разбор всей строки команды перед осуществлением перенаправления потоков ввода/вывода. Следующая команда является хорошо читаемой и корректной:
cat winter.txt > snow.txt 2> errors.txt
2> errors.txt cat winter.txt > snow.txt
Быстрая очистка содержимого файла
А какой самый быстрый способ очистки содержимого файла в случае активации параметра командной оболочки noclobber ?
Практическое задание: перенаправление потоков ввода/вывода
1. Активируйте параметр командной оболочки noclobber .
2. Проверьте, активирован ли параметр noclobber , повторив вызов команды вывода содержимого директории ls для директории /etc с перенаправлением данных из стандартного потока вывода в файл.
3. Какой из символов представляет параметр noclobber в списке всех параметров командной оболочки.
4. Деактивируйте параметр noclobber .
5. Убедитесь в том, что вы имеете доступ к двум командным оболочкам, открытым на одном компьютере. Создайте пустой файл tailing.txt . После этого выполните команду tail -f tailing.txt . Используйте вторую командную оболочку для добавления строки текста в этот файл. Убедитесь в том, что эта строка была выведена в первой командной оболочке.
6. Создайте файл, содержащий имена пяти людей. Используйте команду cat и механизм перенаправления потоков ввода/вывода для создания файла, а также структуру here document для завершения ввода.
Корректная процедура выполнения практического задания: перенаправление потоков ввода/вывода
1. Активируйте параметр командной оболочки noclobber .
2. Проверьте, активирован ли параметр noclobber , повторив вызов команды вывода содержимого директории ls для директории /etc с перенаправлением данных из стандартного потока вывода в файл.
ls /etc > etc.txt ls /etc > etc.txt (команда не должна работать)
3. Какой из символов представляет параметр noclobber в списке всех параметров командной оболочки.
echo $- (параметр noclobber представлен символом C)
4. Деактивируйте параметр 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. Фильтры |