Pipes в Linux: объединение команд через конвейеры
Используйте пайпы (|) в Linux, чтобы передавать вывод одной утилиты как ввод другой. Это позволяет собирать простые, читаемые конвейерные команды вместо монолитных программ. В статье есть практические примеры, разбор именованных пайпов, советы по отладке, шаблоны alias/функций и чек‑листы для быстрого внедрения.

Что такое пайп и зачем он нужен
Пайп (конвейер) — это оператор оболочки |, который перенаправляет стандартный вывод одной программы в стандартный ввод другой. Это основной способ композиции простых программ в Unix‑философии «делай одну вещь и делай её хорошо». Пайпы позволяют:
- Объединять независимые утилиты в логические задачи.
- Писать компактные и гибкие однострочники.
- Ускорять отладку — можно добавлять команды по одной.
Определение: стандартный вывод (stdout) — поток данных, который программа отправляет в терминал; стандартный ввод (stdin) — поток, из которого программа читает данные.
Быстрые примеры и разбор по шагам
Ниже — набор пошаговых примеров, от простых к более сложным. Все команды можно выполнять в bash, zsh или другой POSIX‑совместимой оболочке.
Простой пример: найти файлы по шаблону
У нас есть директория с разными файлами. Нужно посчитать файлы с «page» в имени или расширении.
Список файлов выведет ls:
ls
Фильтруем строки, содержащие “page” при помощи grep:
ls | grep "page"grep выводит только совпадающие строки. Результат — список файлов, содержащих “.page”.

Сложение команд: подсчёт
Добавим wc -l, чтобы посчитать количество строк:
ls -l | grep "page" | wc -lВажно: порядок операций имеет значение. Вывод последней команды в цепочке отображается в терминале.
Выбор полей с помощью awk и сортировка
Выведем размер, владельца и имя файла (поля 5, 3 и 9 в ls -l):
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}'Отсортируем по числовому значению первого столбца (размеру):
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n

Выбрать пять крупнейших
Добавим tail -5, чтобы показать последние пять строк (то есть пять самых больших файлов при сортировке по возрастанию размера):
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5Фразу «показать пять крупнейших .page файлов, упорядоченных по размеру» мы реализовали с помощью пайпов.

Если нужно поменять порядок — используйте sort -nr и head:
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -nr | head -5
Полезные сочетания и реальные примеры
Ниже — примеры, которые часто встречаются в статьях и на практике.
Подсчёт слов/символов в выбранных файлах через xargs
Некоторые утилиты ожидают аргументы, а не поток. xargs преобразует поток в аргументы командной строки:
ls *.page | xargs wcЭто эквивалентно вызову wc file1.page file2.page ....

Список уникальных расширений и их счёт
ls | rev | cut -d'.' -f1 | rev | sort | uniq -cПошагово:
ls— список файлов.rev— обратный порядок символов в строке (удобно, чтобы брать расширение справа налево).cut -d'.' -f1— до первой точки в обратной строке получается расширение.rev— переворачиваем обратно.sort— сортируем, чтобыuniq -cсмог посчитать одинаковые.uniq -c— считает количество одинаковых строк.

Именованные пайпы: как и когда использовать
Именованный пайп (FIFO) — это объект в файловой системе, который остаётся после создания командой mkfifo. В отличие от безымянных пайпов, он существует как файл и переживает перезагрузку (без содержимого). Он полезен, когда процессы, которые обмениваются данными, не запускаются одновременно или когда нужно установить постоянный канал обмена между скриптами.
Создаём именованный пайп:
mkfifo geek-pipeСмотрим детали:
ls -l geek-pipeВ списке файлов первый символ будет p, что означает pipe.
Пример использования в двух терминалах
В первом терминале записываем результаты в именованный пайп:
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipeВ другом терминале читаем содержимое:
cat geek-pipeПроцесс записи будет заблокирован до тех пор, пока другой конец не откроется для чтения. Это поведение называется блокировкой (blocking) и полезно для синхронизации простых сценариев.

Когда пайпы не подходят
Важно понимать ограничения:
- Пайпы передают потоки байтов, а не структуры данных. Для сложных структур используйте IPC, сокеты или файлы с сериализацией (JSON, protobuf).
- Ошибки в одной из команд могут быть потеряны, если вы не перенаправляете stderr.
- Для больших объёмов данных пайп использует память/буфер ядра; для сверхбольших потоков лучше использовать файлы или сокеты.
Совет: перенаправляйте stderr через 2>&1 или используйте отдельную обработку ошибок:
command1 2>errors.log | command2Отладка и проверка промежуточных результатов
Лучший способ писать длинные пайпы — добавлять команды по одной и проверять вывод. Полезные техники:
- Вставляйте
teeдля логирования промежуточного вывода:
cmd1 | tee /tmp/step1.txt | cmd2- Отключайте
grepиawk, если подозреваете, что они фильтруют нужные строки. - Используйте
set -o pipefailв скриптах, чтобы отслеживать неудачу любой команды в пайпе.
Пример включения pipefail в скрипте bash:
#!/bin/bash
set -euo pipefail
cmd1 | cmd2 | cmd3set -o pipefail гарантирует, что код выхода скрипта будет ненулевым, если любая команда в пайпе завершилась с ошибкой.
Альтернативные подходы
Иногда лучше применить другие инструменты:
- Используйте специализированные утилиты (find, sed, perl, rsync) вместо громоздких конвейеров.
- Для параллелизма и надёжности — GNU Parallel или xargs -P.
- Для обмена сложными структурами данных — локальные сокеты, systemd socket activation или named pipes с форматом (JSON, msgpack).
Пример параллельной обработки с xargs:
ls *.page | xargs -n1 -P4 process_fileЭто запустит до 4 параллельных процессов process_file.
Пайпы и безопасность
- Не передавайте секреты через краткоживущие пайпы без шифрования. Процессы на той же машине могут в некоторых случаях прочитать аргументы и часть памяти.
- Будьте осторожны с
evalи генерацией команд из небезопасных входных данных. - Всегда проверяйте пути и расширения перед массовой передачей в
rmили другие разрушительные команды.
Шаблоны и полезные alias/функции
Добавьте в ~/.bashrc или ~/.zshrc несколько полезных алиасов и функций.
Примеры:
alias top-page='ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -nr | head -20'
function ext-count() {
ls "$1" | rev | cut -d'.' -f1 | rev | sort | uniq -c | sort -nr
}После перезагрузки оболочки вызов ext-count . покажет частотность расширений.
Чек‑лист перед использованием пайпов в скрипте
- Тестируйте каждую команду по отдельности.
- Обрабатывайте ошибки (set -euo pipefail).
- [ ] Зафиксируйте форматы вывода (
LC_ALL=Cдля стабильной сортировки). - Подумайте о пределах производительности при больших данных.
- [ ] Логируйте промежуточные данные через
tee.
Ментальные модели и эвристики
- «Одна команда — одна ответственность». Каждая утилита должна решать узкую задачу.
- «Сборка конвейера»: сначала получаем данные (ls/find), затем фильтруем (grep/sed), затем преобразуем (awk/cut/rev), затем агрегируем (sort/uniq/wc), затем выбираем (head/tail).
- «Пиши и проверяй»: добавляй одну команду за раз.
Парадигмы применения по ролям
Разные специалисты будут использовать пайпы по‑разному:
- Админ: быстрое исследование логов (grep | awk | sort | uniq -c).
- Разработчик: подготовка тестовых наборов (jq для JSON, xargs для запуска тестов).
- Аналитик: агрегация данных (cut/awk | sort | uniq).
Примеры на практике: шаблоны задач
- Найти пустые файлы и удалить их с подтверждением:
find . -type f -empty -print0 | xargs -0 -p rm- Список 10 самых больших файлов в каталоге:
find . -type f -printf "%s %p\n" | sort -nr | head -10- Подсчитать уникальные IP в логах:
cat access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -20Критерии приёмки
Перед тем как считать задачу завершённой, проверьте:
- Скрипт корректно обрабатывает пустые входные данные.
- При ошибке любой команды возвращается ненулевой код выхода.
- Логи ошибок пишутся в отдельный файл.
- Производительность приемлема для объёма данных.
Тонкости совместимости и миграции
- В macOS команда
sedи некоторые опцииawk/grepмогут отличаться (BSD vs GNU). Для переносимости используйте POSIX‑совместимые конструкции или установите GNU‑утилиты через Homebrew. - В разных локалях сортировка может отличаться. Для детерминированной сортировки задавайте
LC_ALL=C.
Пример:
LC_ALL=C sort fileШаблон сценария (playbook)
- Напишите команду, которая генерирует сырые данные.
- Добавьте фильтр (grep/sed) и проверьте.
- Добавьте трансформации (cut/awk) и проверьте.
- Добавьте агрегацию (sort/uniq/wc) и проверьте.
- Логируйте промежуточные результаты через
tee. - Добавьте обработку ошибок и документацию.
Мини‑методология тестирования
- Unit: проверяйте отдельные шаги на небольших наборах данных.
- Integration: полный конвейер на типичных данных.
- Edge cases: файлы с пробелами, спецсимволами, пустые потоки.
Тест‑пример для строки с пробелами в имени:
echo "file with spaces.page" > "file with spaces.page"
ls | grep "page" | xargs -I{} echo "X:{}X"Используйте -print0 и xargs -0 при работе с произвольными именами файлов.
Небольшой справочник команд (cheat sheet)
- grep — поиск строк по шаблону
- awk — обработка полей и более сложная логика
- cut — выборка столбцов по разделителю
- sort — сортировка
- uniq -c — подсчёт одинаковых строк
- wc -l — подсчёт строк
- xargs — преобразование потока в аргументы команд
- tee — копирование потока в файл и дальше
- mkfifo — создание именованного пайпа
Мермайд: быстрая схема выбора подхода
flowchart TD
A[Нужна простая фильтрация] -->|да| B[Используйте grep/sed/awk]
A -->|нет| C[Нужна агрегация или подсчёт]
C --> D[sort → uniq -c → wc]
A -->|передача файлов| E[Используйте xargs или find -exec]
E --> F{Нужен параллелизм?}
F -->|да| G[xargs -P или GNU Parallel]
F -->|нет| H[обычный xargs]Примеры ошибок и как их избежать
Проблема: имена файлов с пробелами ломают
ls | xargs. Решение:find . -print0 | xargs -0илиwhile IFS= read -r -d '' f; do ...; done < <(find . -print0).Проблема: потеря ошибок, если команда внутри пайпа провалилась. Решение:
set -o pipefailи логирование stderr.Проблема: нестабильная сортировка между окружениями. Решение:
LC_ALL=C sort.
Когда использовать именованные пайпы
- Когда процессы запускаются в разное время, но нужно постоянное имя канала.
- Для простых межпроцессных коммуникаций на одной машине.
Не используйте именованные пайпы для распределённого обмена данными между машинами — лучше сокеты или сетевые протоколы.
Краткий глоссарий в одну строку
- stdout — стандартный вывод; stdin — стандартный ввод; stderr — стандартный вывод ошибок; pipe — символ | для передачи stdout -> stdin; FIFO — именованный пайп; xargs — конвертер входного потока в аргументы.
Заключение
Пайпы дают мощный и простой способ комбинировать утилиты Unix в гибкие рабочие цепочки. Начинайте с одной команды, добавляйте по одной, логируйте через tee, используйте set -o pipefail и избегайте распространённых ловушек с пробелами в именах и локалями. Именованные пайпы полезны для синхронизации между процессами, но в современной практике чаще используют безымянные пайпы, сокеты и специализированные инструменты.
Важно: практика лучше теории — попробуйте превратить три повседневные задачи в короткие конвейеры, и вы быстро почувствуете эффект.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента