Разбираемся с вводом-выводом в терминале Linux

debianeach

Опубликован:  2019-09-29T11:17:55.981709Z

Продолжаем знакомиться с возможностями терминала Linux. Главной целью и темой для этого обзора послужит ввод/вывод консольных программ, перенаправление ввода/вывода из файла/в файл, а также создание программного канала.

В предыдущем выпуске блога мы определились, что программы в среде Linux делятся на два вида: CLI-программы и GUI-программы. Интересом моего пристального внимания в этом и последующих демонстрациях будут программы командной строки (Command Line Interface), иногда их называют консольными, и принципы, на которых эти программы построены и базируются.

Обычно терминал Linux характеризуется именем прилагательным - текстовый. Это значит, что оператор компьютера вводит с клавиатуры некоторый текст, который представляет из себя имя программы, опции (или ключи) и, не обязательно, имена обрабатываемых этой программой файлов или каталогов. Система исполняет программу с заданными опциями и после выполненных программой действий выводит на терминал некоторый текст, содержащий лаконичную формулировку результатов. Приведу пример, с помощью команды mkdir можно создать на жестком диске компьютера новые каталоги.

mkdir -p -v input/output

vqxYm9Kb6d.png

Я ввёл имя исполняемой программы - mkdir, задал две опции - -p и -v, и ввёл имя каталога, который хочу создать - input/output. В результате исполнения этой программы система выхлопнула на терминал текст:

mkdir: создан каталог 'input'
mkdir: создан каталог 'input/output'

Таким образом терминал воспринимает поток данных от устройства ввода - клавиатуры компьютера, и выводит полученные в результате выполнения команд данные на экран терминала в виде текста. Поток данных от устройства ввода принято называть стандартным потоком ввода или stdin, а поток данных, который выводится на экран терминала в результате выполнения консольных программ, обычно называют стандартным потоком вывода или stdout.

Практически все консольные программы выводят данные в stdout, и только некоторые умеют читать stdin - такие программы принято называть фильтрами. Ещё один пример консольной программы - cat, если cat исполнена без опций, то выводит на терминал введённый с клавиатуры текст после нажатия оператором клавиши Enter.

hW9EgYXCNh.png

Здесь следует заметить, что ввод данных в данном случае можно прервать, послав сигнал EOF (End of File) с помощью клавиатурного сочетания ctrl+d.

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

cd input/output

VGat60IYJw.png

Программа cat поможет нам создать первый файл, для этого я запущу программу без опций и перенаправлю её стандартный поток вывода данных в файл. Такая команда будет выглядеть следующим образом:

cat > unsorted

Здесь я ввёл в приглашении командной строки имя программы - cat, затем символ перенаправления стандартного потока вывода - >, и имя файла, в который этот поток данных будет записан, - unsorted. Посмотрим на терминал.

VALlCa6OLo.png

Как видно на снимке экрана выше, терминал ожидает ввода данных. Введу несколько наборов состоящих из цифр.

6l1AO7SUeW.png

Несложно заметить, что теперь введённые пользователем данные не дублируются последовательным выводом на терминал. Прерываю ввод при помощи ctrl+d, и получаю оглавление текущего каталога при помощи команды ls -l.

IdHJuwIfvz.png

В моём каталоге появился новый файл с именем unsorted. Если посмотреть содержимое этого файла при помощи всё той же программы cat.

cat unsorted

То можно увидеть введённые на предыдущем этапе данные.

dCnHz6TLbj.png

Здесь следует иметь ввиду, что с помощью символа > можно перенаправить данные из stdout в файл и, если файл не существовал до этого, то он будет создан, а если файл существовал, то он будет переписан, а хранящиеся в нём до этого данные будут утеряны. Чтобы добавить данные к существующему файлу необходимо использовать сочетание символов - >>.

cat >> unsorted

FIgVsfBpNd.png

В этом случае введённые ранее данные в файле unsorted будут сохранены, а новые данные будут дописаны в конец файла.

OYLIR4kbCM.png

Рассмотрим ещё одну консольную программу - sort. Введённая без опций команда сортирует данные, поступающие на стандартный поток ввода.

fWtrfGCD2S.png

Как и в предыдущем примере ввод данных можно прервать при помощи ctrl+d, результат своей работы sort выхлопнет на терминал.

iK2YevlUUI.png

На стандартный поток ввода программе sort можно отдать текстовый файл, для этого предназначен символ перенаправления стандартного потока ввода - <.

sort < unsorted

EPf427kgpE.png

Перенаправление стандартных потоков ввода и вывода можно использовать и в одной команде.

sort < unsorted > sorted

KJbxl2VBTq.png

В данном случае я создал в текущем каталоге ещё один файл с именем sorted, в который были записаны отсортированные программой sort данные из файла unsorted.

5cIrPjg6TG.png

Кроме стандартных потоков ввода и вывода существует ещё стандартный поток ошибок - stderr. Программы отдают в stderr данные, полученные в результате возникших при их выполнении ошибок. Стандартный поток ошибок тоже можно перенаправить в файл, для этого используется специальное сочетание символов - 2>.

ls data 2> errors

HX7Z0bZzRT.png

Перенаправление стандартных потоков ввода и вывода из файла и в файл - достаточно часто встречающиеся в повседневной практике действия. Но следует иметь ввиду, что стандартный поток вывода одной команды можно направить в стандартный поток ввода другой команды, для этого используется символ трубы - |, такое перенаправление стандартных потоков обычно называют программным каналом. Свяжем программным каналом две команды - ls и wc. Первая выдаёт на экран терминала оглавление каталога, а вторая считает количество символов, строк и слов. С опцией -l программа wc считает количество строк. Таким образом следующий программный канал:

ls | wc -l

Выведет на экран количество файлов и каталогов хранящихся в текущем каталоге.

i1ITTTzG1I.png

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

bNxuvrvVtQ.png

И мне необходимо получить из этого файла копию в формате MP3. Проблема заключается в том, что кодировщик MP3 - программа lame, на вход принимает только данные в формате WAV, и при этом lame умеет читать данные из стандартного потока ввода. Это значит, что чтобы перекодировать FLAC в MP3 мне придётся использовать промежуточный временный файл в формате WAV, который можно получить, декодировав исходный файл FLAC. Второй вариант действий предполагает создание программного канала между flac и lame - и этот вариант мне нравится больше, потому что он не требует создания временного файла. Вот как это можно реализовать на практике.

flac -d -c test.flac | lame -V 0 - test.mp3

BdFI4UzItg.png

И в результате я получил файл MP3 без создания временного файла WAV.

Tc7jcVzFkr.png

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

Комментарии: