Командная строка Linux, перенаправление ввода и вывода: операторы “>”, “<", "|"
Обновлено 11.11.2024
Приветствую!
Сегодня мы разберём одну из ключевых “фишек” командной строки Linux: механизм перенаправления ввода, вывода и вывода ошибок консольных команд.
Предыдущие посты цикла
Если вы только начинаете изучать Linux, то настоятельно рекомендую посмотреть предыдущие посты:
- Командная строка Linux, введение: типы команд, plain text, файловая система, shell prompt
- Командная строка Linux, навигация в системе и просмотр директорий: команды pwd, ls, cd
- Командная строка Linux, вывод и чтение содержимого: команды echo, cat, less
- Командная строка Linux, работа с файлами: команды touch, mkdir, cp, mv, rm
- Командная строка Linux, ссылки на файлы (links): команда ln
Присоединяйтесь к нашему каналу: 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 является важным навыком для работы в командной строке, который может быть полезным в различных ситуациях её использования.
Успехов в изучении/перенаправлении. Спасибо, что читаете)
Полезные источники
- Перенаправление ввода-вывода – Wikipedia
- Bash-скрипты, часть 4: ввод и вывод – Habr
- Перенаправление стандартного вывода – Раздел книги: Командная строка Linux. Уильям Шоттс
- Мануал команды grep – OpenNET
- Мануал команды sort – OpenNET
- Мануал команды cut – OpenNET
Очень классная статья, спасибо!
Благодарю. Рад, что статья оказалась полезной.