Командная строка Linux, перенаправление ввода и вывода: операторы “>”, “<", "|"

Командная строка Linux, перенаправление ввода и вывода: операторы “>”, “<", "|"

Обновлено 23.02.2024

Приветствую!

Сегодня мы разберём одну из ключевых “фишек” командной строки Linux: механизм перенаправления ввода, вывода и вывода ошибок консольных команд.

Предыдущие посты цикла

Если вы только начинаете изучать Linux, то настоятельно рекомендую посмотреть предыдущие посты:

Присоединяйтесь к нашему каналу: t.me/r4ven_me и чату: t.me/r4ven_me_chat в Telegram .

Введение

Механизм перенаправления работает со стандартными потоками данных в Linux. Вспомним, что это такое.

Стандартные потоки ввода, вывода и вывода ошибок в Linux (и в других операционных системах Unix) являются основными механизмами для взаимодействия между программами и операционной системой. Они представлены следующим образом:

  • Стандартный ввод (stdin) – это поток данных, предназначенных для ввода в программу. Обычно это клавиатура, но также может быть перенаправлен на чтение из файла или другого источника данных.
  • Стандартный вывод (stdout) – это поток данных, предназначенных для вывода результатов работы программы. Обычно это экран терминала, но также может быть перенаправлен на запись в файл или другой программе в качестве аргументов.
  • Стандартный вывод ошибок (stderr) – это поток данных, предназначенных для вывода ошибок и диагностических сообщений программы. Он отличается от стандартного вывода. Этот поток обычно также выводится на экран терминала, но может быть перенаправлен на запись в файл или другой приемник данных.

В Linux и других операционных системах Unix используются специальные символы перенаправления, такие как >, >>, <, << и |, чтобы перенаправлять данные между потоками и файлами.

Практика

Рассмотрим их подробнее.

Оператор перенаправления вывода (stdout) “>

Оператор > используется для перенаправления stdout на указанный файл. Если файл не существует, он будет создан, а если существует, его содержимое будет заменено результатами работы команды. Например, чтобы сохранить вывод команды ls в файле dirs_list.txt, нужно ввести следующую команду:

# перенаправляем вывода в файл
ls > dirs_list.txt

Убедимся, что новый файл появился в текущей директории и посмотрим его содержимое:

ls -l

cat dirs_list.txt

Как видим, после выполнения команды ls > dirs_list.txt в терминале ничего не было отображено, команда молча отработала.

Но проверив содержимое созданного файла убеждаемся, что вывод команды ls был перенаправлен и записан в него.

Обратите внимание на один момент: файл созданный нами в результате нашей команды перенаправления содержит в списке в том числе и наш новый файл dirs_list.txt. Т.е. файл был создан перед выполнением самого перенаправления и поэтому попал в список.

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

# перенаправляем указанный текст в файл
echo "Hello R4ven" > dirs_list.txt

cat dirs_list.txt

Видим, что содержимое файла dirs_list.txt изменилось. Но что делать, если не нужно перезаписывать файл, а добавить новый вывод в конец файла? Для этого существует оператор >>.

Оператор добавления вывода в конец файла “>>

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

# добавляем вывод команды в файл
ls /usr >> dirs_list.txt

cat dirs_list.txt

Видно, что в файле сохранилось предыдущее перенаправление команды echo "Hello R4ven" > dirs_list.txt и с новой строки добавился вывод ls /usr >> dirs_list.txt.

Оператор перенаправления вывода ошибок (stderr) “2>

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

ls wrong_name

Видим сообщение об ошибке. Попробуем выполнить перенаправление и проверить содержимое файла:

ls wrong_name > errors.log

Вывод в терминал сообщения об ошибке все равно происходит и файл пуст. Теперь попробуем с оператором 2>:

# выводим ошибки в файл
ls wrong_name 2> errors.log

cat errors.log

Теперь все отработало как надо: вывод ошибки выполнения команды перенаправился в указанный файл.

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

# выводим потоки в разные файлы
ls /usr /wrong_dir > dirs_list.txt 2> erros.log

cat dirs_list.txt

cat erros.log

Но что, если нужно сохранить оба этих потока в один файл? Сделать это можно двумя способами:

команда > файл_вывода 2>&1

# или

команда &> файл_вывода

Оператором 2>&1 или &> выполняется перенаправление вывода ошибок в тот же файл, в который записывается и обычный вывод. Очевидно, что конструкцию &> легче запомнить, но первый вариант также часто встречается, поэтому знать нужно оба. Выполним несколько команд для наглядности работы этого механизма:

# ошибка выводится в терминал
ls /usr /wrong_dir > dirs_list.txt

cat dirs_list.txt

Ошибка вывелась на экран и не записалась в файл.

# выводим оба потока в один файл
ls /usr /wrong_dir > dirs_list.txt 2>&1

# добавляем другой вывод в тот же файл
cat wrong_file.txt &>> dirs_list.txt

cat dirs_list.txt

После добавления конструкции 2>&1 все отработало, как надо. В один файл были перенаправлены оба потока. Также с помощью конструкции &>> мы добавили два потока другой команды в конец файла.

Оператор перенаправления ввода (stdin) “<

Оператор < используется для перенаправления stdin из указанного файла:

echo "First file" > test_file1.txt

# перенаправляем ввод из файла
cat < test_file1.txt

Второй командой мы указали команде cat взять данные для ввода из файла. Проще конечно было использовать просто cat test_file1.txt, но это была лишь демонстрация работы механизма перенаправления ввода.

В Linux существует команда sort, которая выполняет сортировку вывода по различным параметрам. Давайте попробуем передать ей на ввод содержимое файла, в который мы предварительно запишем содержимое нашего каталога:

ls > test_stdin.txt

# перенаправляем ввод из файла
sort < test_stdin.txt

Тут оператор < передал на ввод команде sort содержимое файла test_stdin.txt.

Существует также оператор <<, который можно использовать для ввода нескольких строк в stdin из командной строки в интерактивном режиме используя команд cat:

cat << EOF > file.txt
This is line 1
This is line 2
EOF

Конструкцией cat << EOF мы выполняем интерактивный ввод в консоль, а затем перенаправляем все это дело в указанный файл.

EOF – тут обозначает начало и конец блока вводимых данных.

EOF (End of File) – это символ, используемый в Linux и других операционных системах для обозначения конца файла или конца потока ввода. Он служит для указания программе, что больше данных для чтения нет. В Linux и многих командных интерпретаторах, таких как Bash, символ EOF может быть введен с клавиатуры, чтобы указать конец ввода. Комбинация клавиш Ctrl+D часто используется для генерации символа EOF.

Оператор конвейера (pipeline) “|

Пожалуй самым интересным для меня механизмом перенаправления в Linux является механизм конвейера, который реализуется с помощью оператора/символа вертикальной черты |.

Оператор | может быть использован для передачи вывода одной программы на вход другой программе (конвейер, он же пайплайн). Например, чтобы определить количество файлов в текущем каталоге, можно использовать команды ls и wc (word count):

# считаем количество файлов в каталоге
ls | wc -l

Ключ -l (line) у команды wc подсчитывает количество строк. Мы с помощью | передали вывод команды ls команде wc, которая определила и вывела на экран сумму выводимых элементов (строк) командой ls.

Другой пример: с помощью cat передадим на ввод команде less длинное содержимое файла, которое не помещается в окне терминала. Такая конструкция часто выполняется для удобства чтения длинного вывода:

# передаем вывод другой команде
cat /etc/passwd | less

Команду less мы рассматривали в этом посте. К слову, никто не запрещает вам использовать команду less напрямую, передав ей в качестве аргумента имя/путь до файла: less /etc/passwd.

Также можно перенаправить stdout, например, утилите grep чтобы отфильтровать вывод любой команды. Для примера возьмём ls:

# фильтруем вывод по шаблону
ls | grep 'txt'

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

Давайте посмотрим пример с уже известной нам командой sort:

# сортируем содержимое каталога
ls | sort

Тут мы отсортировали содержимое текущего каталога в алфавитном порядке (по умолчанию в sort без параметров).

Перенаправлений может быть большое количество. Например:

# многоуровневый пайплайн
ls /etc/ | grep -E 'conf$' | head -n 5 | sort

Тут мы выводим содержимое каталога /etc командой ls, затем фильтруем файлы, имена которых заканчиваются на “conf“, после из всего вывода командой head сокращаем вывод до 5 первых строк и после сортируем их в алфавитном порядке командой sort.

Еще пример:

cat /etc/passwd | grep ivan

# фильтруем поток данных и записываем результат в файл
cat /etc/passwd | grep ivan | cut -d : -f 7 > user_info.txt

cat user_info.txt

Здесь мы командой cat вывели содержимое файла с данными пользователей системы /etc/passwd, затем командой grep отфильтровали вывод по имени пользователя, после чего обрезали вывод по 7-му столбцу командой cut и перенаправили нужный вывод в файл user_info.txt.

С помощью пайплайнов можно очень гибко обрабатывать потоки данных.

Все операторы перенаправления можно комбинировать друг с другом. Способы использования данного механизма в Linux ограничиваются лишь вашей фантазией)

Полезные фишки с операторами перенаправления

1. Простейший текстовые редактор в консоли.

Выполняем команду:

cat > my_text.txt

Затем набираем любой текст (Enter – переход на новую строку):

Hello
this is
plain text
finish with Ctrl+D

Выводим содержимое нашего файла:

cat my_text.txt

2. Перенаправление вывода в “чёрную дыру” – псевдоустройство /dev/null.

Бывают случаи, когда вывод работы какой-либо программы просто не нужен: ни на экране, ни в файле. В таком случае вывод можно перенаправить в специальное псевдоустройство, которое обычно есть в каждом дистрибутиве линукс – /dev/null.

/dev/null в Linux представляет собой специальное устройство (файл), которое является “черной дырой” или нулевым устройством вывода. Когда данные записываются в /dev/null, они фактически игнорируются и уничтожаются. Попросту говоря, любой вывод, который отправляется в /dev/null, просто исчезает, не занимая дисковое пространство и не влияя на другие процессы.

Просто используем правила работы с операторами перенаправления, которые мы рассмотрели выше и смело отправляем любой нужный поток в это устройство:

# вывод содержимого текущего каталога
ls ./

# отправка вывода в "чёрную дыру"
ls ./ > /dev/null

# вывод с ошибкой
ls ./1 > /dev/null

# перенаправление вывода включая ошибки
ls ./1 &> /dev/null

3. Очистка содержимого файла с помощью пустого перенаправления.

Команда такого вида:

> file_name

К примеру у нас есть файл dirs_list.txt с содержимым. Выполняем:

# выводим содержимое для наглядности
cat dirs_list.txt

# перенаправляем пустой вывод
> dirs_list.txt

# вновь проверяем содержимое - пусто
cat dirs_list.txt

Послесловие

В данном посте мы рассмотрели основные аспекты перенаправления ввода-вывода в Linux, включая понятия stdin, stdout и stderr, а также операторы командной строки >, >>, <, << и |. Мы рассмотрели несколько подробных примеров и нюансов использования каждого оператора, а также узнали некоторые интересные фишки этих операторов. В целом, понимание перенаправления ввода-вывода в Linux является важным навыком для работы в командной строке, который может быть полезным в различных ситуациях её использования.

Успехов в изучении/перенаправлении. Спасибо, что читаете)

Полезные источники

  1. Перенаправление ввода-вывода – Wikipedia
  2. Bash-скрипты, часть 4: ввод и вывод – Habr
  3. Перенаправление стандартного вывода – Раздел книги: Командная строка Linux. Уильям Шоттс
  4. Мануал команды grep – OpenNET
  5. Мануал команды sort – OpenNET
  6. Мануал команды cut – OpenNET
Подписаться
Уведомить о
2 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Sveta Saveleva
Sveta Saveleva
07.03.2024 06:57

Очень классная статья, спасибо!