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

Перенаправление потоков ввода-вывода #

Васильев Андрей Михайлович, 2024

Версии презентации


Структура потоков ввода-вывода процесса #

В момент запуска процесса ему выделяются стандартные потоки для ввода и вывода информации

  • 0, stdin — стандартный поток ввода
  • 1, stdout — стандартный поток вывода
  • 2, stderr — стандартный поток вывода сообщений об ошибках

Процесс, инициирующий запуск другого процесса, определяет на какие файловые дескрипторы будут переданы работающему процессу

Процесс во время своей работы может самостоятельно изменить направление потоков, однако эта возможность используется в основном управляющими процессами (например интерпретатором Bash)

diagram


Использование потоками приложением ls #

Приложение ls не использует стандартный поток ввода, данные ему передаются исключительно через аргументы

  • stdout используется для вывода списка файлов
  • stderr используется для вывода информации об ошибках

Пример вывода на стандартный поток вывода:

$ ls -1 /tmp
mc-andrey
mozilla_andrey0
...

Пример вывода на поток ошибок:

$ ls /abc
ls: невозможно получить доступ к '/abc': Нет такого файла или каталога

Без применения специальных действий различить два вывода мы не сможем


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

Bash позволяет перенаправить поток вывода любой команды в файла

КОМАНДА > output_log.txt

Результат работы команды будет записан в файл output_log.txt

diagram


Перенаправление вывода приложения ls #

$ ls -l /usr/bin > /tmp/ls-output.txt
$

В результате запуска пользователю не будет выведено никакой информации, а она будет записана в файл /tmp/ls-output.txt

Перенаправление вывода команды echo #

Поток вывода можно перенаправлять и для встроенных команд Bash

echo 'Hello, world!' > text.txt

В результате будет создан файл text.txt с содержимым 'Hello, world!'


Создание пустых файлов #

Помимо touch можно воспользоваться перенаправлением вывода для создания пустых файлов

> empty.txt

Пустая команда не выводит ничего, в результате будет создан файл empty.txt


Реализация перенаправления #

С технической точки зрения перенаправление потока выглядит следующим образом:

  1. Bash получает команду на перенаправление потока с символом >
  2. Bash открывает указанный файл на запись с флагом w, запись с начала
    • Bash должен иметь возможность открыть файл
    • Всё предыдущее содержимое файла будет удалено
    • Если файла не существовало, тогда он будет создан
  3. Открытый файловый дескриптор устанавливается значением для дескриптора 1, стандартного потока вывода
  4. Происходит запуск нового процесса в изменённом окружении

Добавление в конец файла #

Помимо перезаписи файла Bash может добавлять результаты в конец текстового файла

Синтаксис:

КОМАНДА >> output_log.txt

Стандартный поток вывода будет записан в конец файла output_log.txt

В отличие от предыдущей формы файл открывается с флагом a

Пример с использованием ls #

$ ls -l /usr/bin > ls-output.txt
$ ls -l /usr/bin >> ls-output.txt

В результате выполнения этой последовательности в файле ls-output.txt будет находиться два вывода результата запуска команды ls -l /usr/bin


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

Просмотр потока stderr #

$ ls -l /some > ls-info.txt
ls: невозможно получить доступ к '/some': Нет такого файла или каталога

Хотя stdout был перенаправлен, но приложение всё-равно вывело информацию пользователю


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

Синтаксис:

КОМАНДА 2> error-info.txt

В результате будет создан файл error-info.txt, содержащий информацию из потока stderr запущенной команды

Все данные из потока stdout будут показаны пользователю

diagram


Избавляемся от ошибок #

Бывает так, что приложение посылает много информации на поток stderr и мы хотим его игнорировать. Для этих целей можно воспользоваться специальным файлом /dev/null:

КОМАНДА 2> /dev/null

Все данные, которые записываются в файл /dev/null, пропадают. Это могут использовать любые приложения


Перенаправление двух потоков в один файл #

Для решения этой задачи надо сначала перенаправить stdout в один файл, а затем перенаправить поток stderr в поток stdout:

КОМАНДА > output.txt 2>&1

Форма записи 2>&1 говорит, что поток №2 надо связать с потоком №1

diagram


Порядок указаний на перенаправления важен #

КОМАНДА 2>&1 > output.txt

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

diagram


Новая форма перенаправления потоков #

Если надо перенаправить все потоки в один файл, то можно воспользоваться &>:

КОМАНДА &> output.txt

Добавление в конец файла #

КОМАНДА &>> output.txt

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


Приложение cat #

$ cat --help
Использование: cat [КЛЮЧ]… [ФАЙЛ]…
Печатает слияние ФАЙЛ(ов) на стандартный вывод.

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

Самое простое применение — чтение текстовых файлов

Приложение-повторятель #

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

Простейший текстовый редактор #

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

cat > data.txt

Для завершения работы приложения надо послать сигнал завершения потока Ctrl+D


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

Для перенаправления потока ввода у процесса надо использовать следующий синтаксис:

КОМАНДА < input.txt

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

Вместе с cat его можно использовать для чтения файла:

$ cat < input.txt
...

diagram


Перенаправление для тестирования программ #

При написании консольных программ часто приходится повторять одни и те же действия для проверки работы приложения. Для решения этой задачи удобно

  1. Записать последовательность ввода от пользователя в текстовый файл
  2. Запустить приложение и перенаправить поток ввода из данного файла

В этом случае вам не придётся повторять ввод данных множество раз

Интерактивные приложения #

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

© A. M. Васильев, 2024, CC BY-SA 4.0, andrey@crafted.su