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

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

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

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

  1. Командная строка Linux, введение: типы команд, plain text, файловая система, shell prompt
  2. Командная строка Linux, навигация в системе и просмотр директорий: команды pwd, ls, cd
  3. Командная строка Linux, вывод и чтение содержимого: команды echo, cat, less
  4. Командная строка Linux, работа с файлами: команды touch, mkdir, cp, mv, rm
  5. Командная строка Linux, ссылки на файлы (links): команда ln

Введение

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

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

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

Практика

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

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

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

BASH
# перенаправляем вывода в файл
ls > dirs_list.txt
Нажмите, чтобы развернуть и увидеть больше

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

BASH
ls -l

cat dirs_list.txt
Нажмите, чтобы развернуть и увидеть больше

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

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

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

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

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

cat dirs_list.txt
Нажмите, чтобы развернуть и увидеть больше

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

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

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

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

cat dirs_list.txt
Нажмите, чтобы развернуть и увидеть больше

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

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

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

BASH
ls wrong_name
Нажмите, чтобы развернуть и увидеть больше

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

BASH
ls wrong_name > errors.log
Нажмите, чтобы развернуть и увидеть больше

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

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

cat errors.log
Нажмите, чтобы развернуть и увидеть больше

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

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

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

cat dirs_list.txt

cat erros.log
Нажмите, чтобы развернуть и увидеть больше

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

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

# или

команда &> файл_вывода
Нажмите, чтобы развернуть и увидеть больше

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

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

cat dirs_list.txt
Нажмите, чтобы развернуть и увидеть больше

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

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

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

cat dirs_list.txt
Нажмите, чтобы развернуть и увидеть больше

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

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

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

BASH
echo "First file" > test_file1.txt

# перенаправляем ввод из файла
cat < test_file1.txt
Нажмите, чтобы развернуть и увидеть больше

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

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

BASH
ls > test_stdin.txt

# перенаправляем ввод из файла
sort < test_stdin.txt
Нажмите, чтобы развернуть и увидеть больше

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

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

BASH
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):

BASH
# считаем количество файлов в каталоге
ls | wc -l
Нажмите, чтобы развернуть и увидеть больше

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

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

BASH
# передаем вывод другой команде
cat /etc/passwd | less
Нажмите, чтобы развернуть и увидеть больше

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

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

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

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

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

BASH
# сортируем содержимое каталога
ls | sort
Нажмите, чтобы развернуть и увидеть больше

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

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

BASH
# многоуровневый пайплайн
ls /etc/ | grep -E 'conf$' | head -n 5 | sort
Нажмите, чтобы развернуть и увидеть больше

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

Еще пример:

BASH
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.**Простейший текстовые редактор в консоли.

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

BASH
cat > my_text.txt
Нажмите, чтобы развернуть и увидеть больше

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

BASH
Hello
this is
plain text
finish with Ctrl+D
Нажмите, чтобы развернуть и увидеть больше

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

BASH
cat my_text.txt
Нажмите, чтобы развернуть и увидеть больше

**2.**Перенаправление вывода в «чёрную дыру» — псевдоустройство /dev/null.

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

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

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

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

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

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

# перенаправление вывода включая ошибки
ls ./1 &> /dev/null
Нажмите, чтобы развернуть и увидеть больше

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

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

BASH
> file_name
Нажмите, чтобы развернуть и увидеть больше

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

BASH
# выводим содержимое для наглядности
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

Авторские права

Автор: Иван Чёрный

Ссылка: https://r4ven.me/linux/komandnaya-stroka-linux-perenapravlenie-vvoda-i-vyvoda/

Лицензия: CC BY-NC-SA 4.0

Использование материалов блога разрешается при условии: указания авторства/источника, некоммерческого использования и сохранения лицензии.

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша