open atlas
↑ К треку
Командная строка CLI · 03 · 03

Конвейеры и grep

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

CLI Junior ◷ 22 min
Уровень
ОсновыJuniorMiddleSenior

Ты узнал, что команды читают из stdin и пишут в stdout. Конвейер — это механизм, позволяющий соединить эти два канала: stdout одной команды становится stdin следующей. Эта единственная идея — соединение небольших, узкоспециализированных инструментов в цепочку — и есть философия Unix в действии. Вместо одной монолитной программы, которая ищет, фильтрует, считает и форматирует, ты соединяешь простые инструменты последовательно. grep — незаменимый фильтр: получив поток строк, он пропускает только те, которые соответствуют шаблону, и отбрасывает остальные.

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

Цель

После этого урока ты сможешь использовать | для подключения stdout одной команды к stdin другой, использовать grep ШАБЛОН для фильтрации строк, содержащих шаблон, использовать grep -v для инверсии фильтра, использовать grep -i для поиска без учёта регистра и соединять несколько конвейеров в цепочку.

1

| (пайп, канал) соединяет stdout левой команды с stdin правой. Оболочка создаёт канал ядра — буфер в памяти — и настраивает два процесса так, что один пишет в него, а другой читает из него. Оба процесса работают одновременно (параллельно), а не один за другим. Писатель блокируется, если буфер заполняется; читатель блокируется, если буфер пустеет. Ядро координирует их.

ls /etc | less

ls /etc записывает имена файлов в канал; less читает из канала и позволяет прокручивать. Ни одна команда не знает о другой — ls просто пишет в stdout (который оказывается каналом), а less просто читает из stdin (который оказывается каналом).

2

grep ШАБЛОН выводит только строки, содержащие ШАБЛОН. Он читает из stdin (или файла) построчно. Если строка содержит шаблон, она проходит в stdout. Если не совпадает — тихо отбрасывается.

cat /etc/passwd | grep bash

Вывод: только строки в /etc/passwd, содержащие строку “bash”. Это пользователи, чья оболочка — /bin/bash.

Без конвейера grep принимает имя файла:

grep bash /etc/passwd

Тот же результат. Форма с конвейером более полезна, когда сам ввод приходит от другой команды.

3

grep -v инвертирует совпадение — выводит строки, которые НЕ совпадают. Это вариант «отфильтровать».

cat /etc/passwd | grep -v nologin

Каждая строка, не содержащая “nologin”, проходит. Это быстрый способ убрать строки комментариев, служебные учётные записи или известный шум из потока.

grep -i делает совпадение нечувствительным к регистру.

ps aux | grep -i nginx

Совпадает с “nginx”, “Nginx”, “NGINX” — любой вариант регистра.

Оба флага можно комбинировать: grep -iv шаблон — нечувствительно к регистру и инвертированно.

4

Можно соединять несколько конвейеров в цепочку. Каждый | добавляет ещё одну стадию. Вывод стадии N становится вводом для стадии N+1.

ps aux | grep nginx | grep -v grep

Стадия 1: ps aux выводит список всех запущенных процессов. Стадия 2: grep nginx оставляет только строки, упоминающие nginx. Стадия 3: grep -v grep удаляет строку, которая упоминает само слово “grep” (процесс grep появляется в собственном выводе, что обычно является шумом).

Это основной шаблон: начать с производителя, отфильтровать одной или несколькими стадиями grep, затем передать потребителю.

5

grep поддерживает базовые регулярные выражения. Обычная строка вроде bash совпадает буквально. Регулярное выражение вроде ^root совпадает со строками, которые начинаются с “root” (^ привязывает к началу строки). root$ совпадает со строками, заканчивающимися на “root” ($ привязывает к концу строки). Точка . совпадает с любым одним символом. Используй -E (или egrep) для расширенного regex с +, ?, |, ().

grep '^root' /etc/passwd

Совпадает только со строками, первый символ которых ‘r’, второй ‘o’, третий ‘o’, четвёртый ‘t’ — строка пользователя root.

Для повседневной фильтрации обычных строк достаточно 90% случаев. Regex становится важным, когда нужны якоря или чередование.

Разбор примера

Найти все процессы, слушающие на порту 80.

ss -tlnp | grep ':80'

ss -tlnp выводит TCP-сокеты в режиме прослушивания с информацией о процессе. grep ':80' оставляет только строки, содержащие “:80” — строки для порта 80. Результат — краткий ответ на вопрос «что находится на порту 80?» без ручного просмотра сотен строк.

Добавь второй фильтр для сужения — только строки не от root:

ss -tlnp | grep ':80' | grep -v 'root'

Теперь расширь поиском без учёта регистра любого веб-сервера:

ps aux | grep -i 'nginx\|apache\|caddy'

\| в базовом regex означает «или». Это совпадает с любым из трёх имён веб-серверов. Шаблон конвейера масштабируется: каждый дополнительный | добавляет один целенаправленный фильтр.

Почему это работает

На macOS grep — это BSD grep, который немного отличается от GNU grep (Linux по умолчанию). Флаги -v, -i, -E работают идентично. Главное отличие: -P (Perl-совместимые regex) в BSD grep недоступен на старых версиях macOS. Для переносимых скриптов используй -E для расширенных regex вместо -P. Все примеры в этом уроке используют только базовые или расширенные шаблоны, работающие на обеих платформах.

Частая ошибка

grep завершается с ненулевым статусом, когда ни одна строка не совпала. В конвейере внутри скрипта с set -e grep, ничего не нашедший, убивает скрипт. Исправление — добавить || true после grep, когда «нет совпадений» — допустимый результат: some_command | grep шаблон || true. Это говорит оболочке «код выхода 1 от grep здесь допустим».

Проверь себя
Викторина

Ты запускаешь: ps aux | grep python | grep -v grep. Что делает финальная стадия grep -v grep?

Итог

Оператор конвейера | соединяет stdout одной команды с stdin следующей, при этом оба процесса выполняются одновременно через буфер ядра. grep ШАБЛОН — фильтр строк: совпадающие строки проходят, несовпадающие отбрасываются. grep -v инвертирует совпадение; grep -i игнорирует регистр. Можно соединять любое количество конвейеров для построения многоступенчатых конвейеров обработки текста. Каждая стадия — узкоспециализированный инструмент, делающий одно дело; конвейер — соединительная ткань. Это философия Unix: маленькие программы, соединённые конвейерами, делающие вместе больше, чем любая из них в отдельности.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.