# Конвейеры и перенаправление (pipes)

> Механизмы оболочки Unix для соединения программ — конвейер | передаёт вывод одной команды на вход другой, а перенаправления >, <, 2> связывают потоки с файлами.

Источник: https://llmdocs.ru/wiki/pipes-redirection/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Идея конвейеров**: Дуглас Макилрой (1964)
- **Реализация в Unix**: Кен Томпсон, Unix Version 3 (1973)
- **Стандартные потоки**: 0 — stdin, 1 — stdout, 2 — stderr
- **Операторы**: |, >, >>, <, 2>, 2>&1, &>, <<, <<<
- **Связанные механизмы**: tee, именованные каналы (mkfifo), подстановка процессов
- **Принцип**: маленькие программы, каждая делает одно дело
**Конвейер** (англ. *pipe*, «труба», в жаргоне — «пайп») — механизм Unix, который соединяет стандартный вывод одной программы со стандартным вводом другой: `команда1 | команда2`. **Перенаправление** связывает потоки ввода-вывода с файлами: `команда > out.txt`. Вместе они воплощают философию Unix: вместо одной большой программы, делающей всё, — маленькие утилиты, каждая из которых делает одно дело хорошо, соединяемые в цепочки.

Конвейеры — основа повседневной работы в [командной строке](https://llmdocs.ru/wiki/shell-bash.md) [Linux](https://llmdocs.ru/wiki/linux.md): найти в логе ошибки, отсортировать, посчитать, взять первые десять — одной строкой.

## История

Идею соединять программы «как садовые шланги» высказал Дуглас Макилрой в служебной записке Bell Labs ещё в 1964 году. В 1973 году Кен Томпсон за одну ночь добавил в Unix системный вызов `pipe()` и синтаксис с вертикальной чертой, переписав утилиты так, чтобы они читали стандартный ввод и писали в стандартный вывод. Этот момент часто называют рождением «философии Unix».

## Стандартные потоки

Каждый процесс начинает работу с тремя открытыми потоками — **файловыми дескрипторами**:

| Номер | Имя | Назначение | По умолчанию |
|---|---|---|---|
| 0 | stdin | стандартный ввод | клавиатура |
| 1 | stdout | стандартный вывод | экран |
| 2 | stderr | поток ошибок | экран |

Разделение вывода и ошибок важно: при `команда > file` в файл уходят данные, а сообщения об ошибках по-прежнему видны на экране и не портят результат.

## Перенаправления

```bash
ls > files.txt              # stdout в файл (перезаписать)
ls >> files.txt             # дописать в конец
sort < names.txt            # stdin из файла
make 2> errors.log          # только stderr в файл
cmd > out.log 2>&1          # оба потока в один файл (порядок важен!)
cmd &> out.log              # то же, сокращение Bash
cmd 2>/dev/null             # выбросить ошибки
cmd > /dev/null 2>&1        # выбросить всё
```

Запись `2>&1` означает «направить поток 2 туда же, куда сейчас направлен поток 1». Поэтому `cmd 2>&1 > file` отправит ошибки на экран, а в файл — только вывод: перенаправления применяются слева направо.[2]

### Here-документ и here-строка

```bash
cat <<EOF > config.ini
[server]
host = $HOSTNAME
port = 8080
EOF

grep -c "a" <<< "banana"       # строка как stdin
```

Внутри `<<EOF` переменные раскрываются; чтобы передать текст буквально, ограничитель берут в кавычки: `<<'EOF'`.

## Конвейеры

```bash
cat access.log | grep " 500 " | wc -l                  # число ошибок 500
ps aux | sort -k4 -rn | head -5                         # 5 процессов, потребляющих больше всего памяти
journalctl -u nginx --since today | grep -i error | less
du -sh * | sort -h | tail                               # самые большие каталоги
curl -s https://api.github.com/repos/python/cpython | jq '.stargazers_count'
```

Программы конвейера запускаются **одновременно**, и данные текут между ними порциями через буфер ядра (обычно 64 КБ в Linux), не накапливаясь целиком.[3] Если следующая программа читает медленнее, предыдущая ждёт; если она завершилась (как `head`), предыдущая получает сигнал SIGPIPE и тоже завершается (см. [Процессы и сигналы](https://llmdocs.ru/wiki/processes-signals.md)). Поэтому `head` по огромному файлу работает мгновенно.

### Коды выхода

Код выхода конвейера по умолчанию — код *последней* команды: `false | true` считается успехом. В скриптах это скрывает ошибки, поэтому используют `set -o pipefail` — тогда конвейер завершается неуспешно, если упала любая из команд. Коды всех команд доступны в массиве `PIPESTATUS`.[1]

## Полезные приёмы

- **`tee`** раздваивает поток: пишет и в файл, и дальше по конвейеру — `make 2>&1 | tee build.log`. Запись в файл с правами root: `echo "..." | sudo tee /etc/file`.
- **Подстановка процессов** `<(команда)` подставляет вывод команды как временный файл: `diff <(sort a.txt) <(sort b.txt)`.
- **Подстановка команд** `$(команда)` вставляет вывод в строку: `kill $(pgrep -f worker)`.
- **Именованные каналы** (`mkfifo /tmp/pipe`) — конвейер в виде файла, через который могут общаться независимые процессы.[5]
- **`xargs`** превращает поток строк в аргументы команды (см. [find и xargs](https://llmdocs.ru/wiki/find-xargs.md)).

## Классический пример

Подсчёт десяти самых частых слов в тексте — задача, на которой Макилрой в 1986 году показал силу конвейеров:

```bash
tr -cs '[:alpha:]' '\n' < book.txt | tr '[:upper:]' '[:lower:]' | sort | uniq -c | sort -rn | head
```

Каждая утилита проста: `tr` разбивает текст на слова и приводит к нижнему регистру, `sort` и `uniq -c` считают повторы, `sort -rn` упорядочивает, `head` берёт верхушку. Те же блоки решают и десятки других задач — для полей и сумм удобен [awk](https://llmdocs.ru/wiki/sed-awk.md), для поиска — [grep](https://llmdocs.ru/wiki/grep.md), для JSON — [jq](https://llmdocs.ru/wiki/json.md).

## Ограничения

Конвейеры передают неструктурированный текст: каждая программа заново разбирает строки, и пробелы в именах файлов или неожиданный формат вывода ломают цепочку. Для сложной логики и структурированных данных лучше подходят [Python](https://llmdocs.ru/wiki/python.md) или оболочки нового поколения, передающие объекты (PowerShell, Nushell). Синтаксис конвейеров и перенаправлений закреплён в стандарте POSIX и одинаково работает в Bash, Zsh и dash.[4]

## См. также

- [Shell и Bash](https://llmdocs.ru/wiki/shell-bash.md)
- [grep и регулярные выражения](https://llmdocs.ru/wiki/grep.md)
- [sed и awk](https://llmdocs.ru/wiki/sed-awk.md)
- [find и xargs](https://llmdocs.ru/wiki/find-xargs.md)
- [Процессы и сигналы](https://llmdocs.ru/wiki/processes-signals.md)

## Источники

1. [GNU Bash manual — Pipelines](https://www.gnu.org/software/bash/manual/html_node/Pipelines.html)
2. [GNU Bash manual — Redirections](https://www.gnu.org/software/bash/manual/html_node/Redirections.html)
3. [pipe(7) — Linux manual page](https://man7.org/linux/man-pages/man7/pipe.7.html)
4. [POSIX.1-2024 — Shell Command Language](https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html)
5. [mkfifo(1) — Linux manual page](https://man7.org/linux/man-pages/man1/mkfifo.1.html)
