Программы
Bash < потоки ввода > вывода && управляющие конструкции || коротко о главном

Bash < потоки ввода > вывода && управляющие конструкции || коротко о главном

Небольшая заметка о конструкциях Bash, в которых путается большинство новичков. А именно: >, <, &, &&, |, ||

В Bash, да и других командных оболочках (даже в cmd.exe) есть довольно странные символы для управления потоками ввода/вывода, управления потоком исполнения. Одни из наиболее часто используемых это: >, <, &, &&, |, ||. Выглядят они похоже, да и иногда имеют схожий смысл, но, само собой – всё это разные операции.

Потоки вывода / ввода и файлы

Для начала разберёмся с первыми двумя. Во-первых, >, < – это всё про файлы или про дескрипторы файлов (некоторые их представления). И это действительно базовые вещи, например, если мы хотим сохранить вывод команды в файл, то мы пишем:

help > help_info.txt

– где help – это команда, вывод которой мы хотим сохранить, а help_info.txt – это файл, куда сохранить. То есть обычный вывод мы можем сохранить в файл с помощью перенаправления потока стандартного вывода (>).

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

Но если есть вывод, значит можно сделать аналогично на ввод. Например, команда wc умеет считать слова/строки/байты, переданные на стандартный поток ввода. Передадим и мы из нашего файла help_info.txt:

wc -l < help_info.txt

И узнаем, сколько же строк было в выводе help. Тут важно понять, что это не из-за того, что в одном случае "стрелка" была от программы, а в другом – в программу, хотя так и выглядит. Просто > всегда пытается записать в файл, а < – прочитать из файла. К примеру, мы можем попытаться сразу посчитать строки, которые выдаёт help:

help > wc

Но вместо этого мы создадим файл "wc" и запишем в него вывод команды help.

Потоки вывода / ввода и программы

А вот что реально поможет с переводом стандартного потока вывода на вход другой программы – так это "труба" – |, также известная как конструкция "пайп" (калька с английского "pipe"). По трубе можно слева направо лить данные, изменяя их как на конвейере:

help | wc -l

– сработает уже ожидаемо. Можно делать более сложные "каскады" из труб:

ifconfig | grep inet | grep -v inet6 | cut -d ' ' -f 2

Работает это следующим образом:

  1. Получаем вывод команды ifconfig с подробной информацией о сетевых интерфейсах.
  2. Отфильтровываем строки, оставляя те, что с подстрокой "inet" командой grep.
  3. Из результата убираем строки с подстрокой "inet6" (не интересуемся IPv6).
  4. Разделяем строки на столбцы по пробелу и берём 2-ой столбец с помощью cut.

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

Управляющие конструкции в Bash

Хорошо, поняли, что | перенаправляет данные из одной программы в другую... Но есть ещё и || – может он делает это как-то лучше? На самом деле, || вообще никак не связан с |, хоть и похож. Он нужен для управления последовательностью действий.

Как в языках программирования есть условные операторы (в Bash они тоже есть), так и в терминале иногда удобно задать последовательность действий, исходя и того, получилось ли предыдущее. Например, перейти в директорию "asd", а если не удалось (скорее всего её нет) – создать её:

cd asd || mkdir asd

|| проверит код завершения предыдущей команды, и если он не 0 (а именно 0 считается корректным и правильным), то выполнится. Сам код завершения последней программы можно посмотреть в переменной $? (в Windows – %errorlevel%):

$ cd asd
-bash: cd: asd: No such file or directory

$ echo $?
1

– код не 0, значит в примере выше, мы бы попытались создать директорию... И было бы логично в неё заодно так и перейти. То есть "перейти в директорию "asd", а если не удалось (скорее всего её нет) – создать её и, если создали, перейти в неё". Для этого есть противоположность ||&&. Он выполнит следующую команду, если предыдущая завершилась хорошо. Если || называют "логическим или" (исключающим), то && – "логическое и". А наш пример превращается в:

cd asd || mkdir asd && cd asd

Мы можем таким образом описывать условия, как и с if.

Запуск программ в фоне на Bash

Казалось бы, как мы пришли к этому подзаголовку? Ровно также, как и к "управляющим конструкциям": у && есть довольно похожий на него "близнец" – &. И опять у них нет ничего общего. Если первый позволяет управлять потоком исполнения команд, то второй запускает их в фоне!

Например, давайте запустим простую, но долгую программу в фоне, выполним другую программу, а потом вернём из фона первую программу.

$ sleep 100 &
[1] 4925
$ echo "Hello"
Hello
$ jobs
[1]+  Running                 sleep 100 &
$ fg 1
sleep 100
^C

С помощью команды jobs можно получить список запущенных в сессии терминала задач. Задачи пронумерованы – по этим номерам можно поднимать задачи из фонового режима командой fg.

Это может быть удобно, если нужно запустить несколько задач, а терминал только один, либо же если хочется наплодить кучу независимых процессов (например, для параллельно обработки данных).

Завершение, о чём не рассказал

Как можно было заметить, в Bash довольно много странных символов, имеющих важные значения. Более того – не обязательно похожие комбинации символов означают похожее. Понимание приходит с опытом / привычкой.

У того же амперсанда есть и другие смыслы, в зависимости от контекста: и "битовое и" и "запись в открытый дескриптор". Да и <<, и даже <<< здесь не были упомянуты. В заметке скорее обзор самых первых удивлений, которые возникают у студента при знакомстве с терминалом / Bash-ем.

Если также часто придётся рассказывать про иные особенности - появится и их описание, как это было с "Как запустить программу в терминале в фоне, без вывода какого либо текста".

Ну и в целом, если заинтересовались – "Трюки Bash" для вас!

Также может быть вам интересно:

Столлман мне друг, но этикет дороже

Столлман – активист и лидер GNU, бывший директор Фонда Свободного Программного обеспечения. Кому и почему он неудобен?

Читать »

Социальная сеть – фильм о создании Facebook

Фильм о создании и создателях самой большой социальной сети в мире. Марк Цукерберг – гений программирования или же обмана?

Читать »
Фото Как установить PostgreSQL на Linux и создать базу и пользователя

Как установить PostgreSQL на Linux и создать базу и пользователя

PostgreSQL - система управления базой данных общего назначения. Одна из самых распространённых баз данных, используемая на многих коммерческих и некоммерческих проектах.

Фото Как сделать свою middleware в Django (с примерами)

Как сделать свою middleware в Django (с примерами)

Middleware или "промежуточное программное обеспечение" - элегантный способ установить общие правила обработки запросов и ответов приложения. Давайте напишем парочку middleware, чтобы понять, как они работают.

Фото Как настроить отправку почты из Django

Как настроить отправку почты из Django

Письма об ошибках, отчёты на почту, восстановление паролей - всё это полезно при работе с сайтом. Django предоставляет удобный способ это сделать с минимумом настроек!

Фото Добавляем поддержку медиа-файлов в Django проект

Добавляем поддержку медиа-файлов в Django проект

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

Фото Добавляем постраничную пагинацию на Django сайт

Добавляем постраничную пагинацию на Django сайт

На сайтах часто встречаются многостраничные объекты: список товаров, список заметок и т.д. Поэтому важно уметь добавить навигацию по страницам на Django-проекте.

Фото Новый оператор match-case в Python

Новый оператор match-case в Python

В новой версии Python (3.10) появится новый оператор. Новый оператор сопоставления по шаблону (match-case).

Фото Нет слов, одни... однострочники

Нет слов, одни... однострочники

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

Фото Microsoft открывает исходники, а её IDE супер-популярна

Microsoft открывает исходники, а её IDE супер-популярна

Решил сложить пару фактов и немного над этим поразмыслить. Реально ли Microsoft "переобулись"?