Найти тему

Linux. Стандартный ввод, вывод и ошибки.

Оглавление

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

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

Ну с выводом более-менее разобрались. А как обстоят дела с вводом? Все так же. Большинство программ на самом деле принимают ввод из специального файла с названием стандартный ввод (или stdin). И он, по умолчанию, связан с клавиатурой, но опять таки, может быть изменен.

Перенаправление stdout.

Для перенаправления вызова используется оператор >. Например, следующая строка перенаправит вызов команды ls в файл ls-output.txt

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

На экран ничего не выведется, но если посмотреть в текущую директорию

$ls -l
-rw-r--r-- 1 user users 54 Apr 23 17:49 ls-output.txt

появился файл ls-output.txt. Если заглянете в содержимое, то и увидеть весь вывод команды. А что, если мы укажем не существующий каталог

$ls -l /dwsd > ls-output.txt
ls: cannot access '/dfsa': No such file or directory

На экран будет выведено сообщение об ошибке. Но почему же оно не улетело в файл? Дело в том, что команда ls не засоряет свой стандартный вывод ошибками, а использует для этого стандартный вывод ошибок. О том как туда все перенаправить чуть ниже, а сейчас ради интереса проверьте файл ls-output.txt. Могу поспорить, он будет пустой.

Дело в том, что оператор > всегда начинает запись в файл с самого начала, несмотря на имеющиеся в нем данные, и просто стирает их. Кстати, благодаря этой особенности, с помощью этого оператора можно создавать файлы или стирать в них данные. Примерно так

$ > file

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

Перенаправление stderr.

С стандартным выводом ошибок не все так просто, как со стандартным. Чтобы перенаправить этот вывод, надо передать оператору перенаправления дескриптор файла. Обычно в системе есть три файловых дескриптора:

0 - стандартный ввод
1 - стандартный вывод
2 - стандартный вывод ошибок

С помощью этих дескрипторов ошибки можно перенаправлять отдельно

$ls -l /dwsd 2> ls-error.txt

Такой вызов запишет все ошибки в файл ls-error.txt.

Иногда, надо сохранить весь вывод команды в один файл. Сделать это можно двумя способами. Первый, это перевод стандартного вывода в файл, а стандартный вывод ошибок в стандартный вывод. Например,

$ls -l /bin > ls-output.txt 2>&1

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

И второй способ использовать оператор &>. Этот оператор перенаправляет оба потока и стандартный вывод и стандартный вывод ошибок

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

А что, если нам не нужен какой-нибудь вывод ни в файле, ни на экране. Для этого в Linux есть специальный файл /dev/null, куда можно перенаправить свой вывод. Например, чтобы подавить вывод об ошибках, можно их отправить в эту мусорную корзину.

$ls -l /dfww 2> dev/null

Перенаправление stdin.

Для того, чтобы разобраться, давайте рассмотрим команды cat. Работа ее заключается в копировании содержимого файла и направляет его на стандартный вывод. Синтаксис такой

$cat файл

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

$cat
Что-нибудь.
Что-нибудь.

То, что вы введете с клавиатуры, тут же будет выведено на экран. Так как и есть работа команды cat, что-то брать из ввода и перенаправлять на вывод. Чтобы закончить работу с командой надо нажать ctrl+D.

Теперь давайте перенаправим вывод команды.

$cat > file

Вводим текст. И этот текст попадает в файл file. А теперь сделаем следующее

$cat < file

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

Заключение.

Вот немного разобрались с потоками. Теперь немного знаем, как ими управлять. Эти знания обязательно пригодятся. Это я вам обещаю. Каждый день на работе этим пользуюсь. Ну и все на сегодня, пожалуй.

А пока подписывайтесь на мой канал. И про телеграмм тоже не забываем.