Каналы и перенаправление
Updated Jul 2026
Философия Unix: маленькие инструменты, большие результаты
Каналы (|) соединяют вывод одной команды со входом другой. Перенаправление (>, >>, <) соединяет команды с файлами. Вместе они позволяют строить мощные конвейеры обработки данных из простых строительных блоков.
Это философия Unix: каждая команда делает одну вещь хорошо, а каналы объединяют их в рабочие процессы, которые ни одна отдельная команда не могла бы выполнить самостоятельно.
Каналы
Оператор канала | берёт стандартный вывод (stdout) левой команды и передаёт его как стандартный ввод (stdin) правой команде.
Базовые примеры каналов
# Подсчитать, сколько POST-запросов вернули 500
grep "POST /api" /var/log/nginx/access.log | grep "500" | wc -l
# Найти 10 самых частых сообщений об ошибках
grep "ERROR" app.log | sort | uniq -c | sort -rn | head -10
# Показать уникальные IP-адреса, обращающиеся к серверу
awk '{print $1}' /var/log/nginx/access.log | sort -u | wc -l
# Найти самые большие файлы в каталоге
du -sh * | sort -rh | head -5
Разбор сложного конвейера
Давайте проследим пример «10 самых частых сообщений об ошибках» пошагово:
# Шаг 1: Получить все строки с ERROR
grep "ERROR" app.log
# Вывод: сотни строк с ошибками
# Шаг 2: Отсортировать (обязательно для uniq)
grep "ERROR" app.log | sort
# Вывод: строки ошибок в алфавитном порядке
# Шаг 3: Подсчитать последовательные дубликаты
grep "ERROR" app.log | sort | uniq -c
# Вывод:
# 47 ERROR: Connection timeout to payment-service
# 23 ERROR: Invalid session token
# 12 ERROR: Database query exceeded timeout
# Шаг 4: Отсортировать по количеству (по убыванию, числовая)
grep "ERROR" app.log | sort | uniq -c | sort -rn
# Вывод: Самые частые ошибки первыми
# Шаг 5: Показать только топ-10
grep "ERROR" app.log | sort | uniq -c | sort -rn | head -10
# Вывод: 10 самых частых сообщений об ошибках с подсчётом
Перенаправление
Перенаправление соединяет ввод и вывод команд с файлами вместо терминала.
Перенаправление вывода
# Записать вывод в файл (перезаписать)
curl -s https://api.example.com/users > users.json
# Дополнить файл выводом
echo "Test run completed at $(date)" >> test-log.txt
# Записать в файл и одновременно показать на экране
curl -s https://api.example.com/users | tee users.json
# Дополнить с tee
echo "Another result" | tee -a test-log.txt
Перенаправление ошибок
Linux имеет три стандартных потока:
- stdin (0): Стандартный ввод
- stdout (1): Стандартный вывод (обычный вывод)
- stderr (2): Стандартный поток ошибок (сообщения об ошибках)
# Перенаправить только ошибки в файл
npm run test 2> errors.log
# Перенаправить stdout и stderr в один файл
npm run test > output.log 2>&1
# Перенаправить stdout и stderr в разные файлы
npm run test > output.log 2> errors.log
# Отбросить весь вывод (полезно для скриптов, где важен только код возврата)
curl -s https://api.example.com/health > /dev/null 2>&1
# Отбросить только ошибки (подавить шум "Permission denied" от find)
find / -name "config.json" 2>/dev/null
Перенаправление ввода
# Прочитать ввод из файла
sort < unsorted-list.txt
# Here document (встроенный ввод)
cat <<EOF > test-config.json
{
"baseURL": "https://staging.example.com",
"timeout": 30000
}
EOF
# Here string (однострочный ввод)
grep "error" <<< "This has an error in it"
Основные команды для конвейеров
Эти команды наиболее полезны в комбинации с каналами:
sort
# Алфавитная сортировка
sort names.txt
# Числовая сортировка
sort -n numbers.txt
# Обратная сортировка
sort -r names.txt
# Сортировка по конкретному столбцу (например, 3-му)
sort -t',' -k3 data.csv
# Числовая обратная сортировка (самый частый вариант в цепочках)
sort -rn
uniq
uniq удаляет последовательные дублирующиеся строки. Всегда выполняйте sort перед uniq.
# Удалить дубликаты
sort names.txt | uniq
# Подсчитать вхождения
sort names.txt | uniq -c
# Показать только дубликаты
sort names.txt | uniq -d
# Показать только уникальные строки (без дубликатов)
sort names.txt | uniq -u
wc (подсчёт слов)
# Подсчёт строк
wc -l file.txt
# Подсчёт слов
wc -w file.txt
# Подсчёт символов
wc -c file.txt
# Подсчёт строк из канала (самое частое использование)
grep "ERROR" app.log | wc -l
head и tail
# Первые 10 строк (по умолчанию)
head file.txt
# Первые 20 строк
head -20 file.txt
# Последние 10 строк (по умолчанию)
tail file.txt
# Последние 50 строк
tail -50 file.txt
# Мониторинг файла в реальном времени (отслеживание логов)
tail -f /var/log/app/application.log
# Мониторинг с показом последних 100 строк
tail -100f /var/log/app/application.log
cut
# Извлечь конкретные столбцы из разделённых данных
cut -d',' -f1,3 data.csv # Поля 1 и 3, разделитель -- запятая
cut -d':' -f1 /etc/passwd # Имя пользователя из файла passwd
cut -c1-10 file.txt # Первые 10 символов каждой строки
tr (трансляция)
# Преобразовать в верхний регистр
echo "hello" | tr 'a-z' 'A-Z'
# Вывод: HELLO
# Заменить пробелы на переносы строк
echo "one two three" | tr ' ' '\n'
# Удалить конкретные символы
echo "Hello, World!" | tr -d '!,'
# Вывод: Hello World
# Сжать повторяющиеся символы
echo "hello world" | tr -s ' '
# Вывод: hello world
xargs
# Передать вывод канала как аргументы команде
find . -name "*.spec.ts" | xargs grep "test.only"
# Удалить файлы, найденные find
find /tmp -name "*.log" -mtime +7 | xargs rm
# Выполнить команду для каждой строки ввода
cat urls.txt | xargs -I {} curl -s -o /dev/null -w "{}: %{http_code}\n" {}
Практические цепочки каналов для QA
Анализ логов доступа Nginx
# Топ-10 самых запрашиваемых URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# Топ-10 IP-адресов по количеству запросов
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# Подсчёт запросов по HTTP-коду статуса
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# Все ошибки 500 с временными метками
grep " 500 " /var/log/nginx/access.log | awk '{print $4, $7}' | tail -20
Анализ результатов тестов
# Подсчёт пройденных/упавших/пропущенных из JUnit XML
grep -c 'status="passed"' test-results/*.xml
grep -c 'status="failed"' test-results/*.xml
# Найти все тестовые файлы, содержащие .only (случайно сфокусированные тесты)
grep -rl "\.only" tests/ --include="*.spec.ts"
# Список всех описаний тестов
grep -rh "test\('" tests/ --include="*.spec.ts" | sed "s/.*test('//" | sed "s/',.*//" | sort
Мониторинг и проверки здоровья
# Проверить несколько эндпоинтов и показать статус
for url in https://api.example.com/health https://web.example.com https://admin.example.com; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$url")
echo "$url: $STATUS"
done
# Мониторить лог-файл на ошибки и отправлять оповещение
tail -f /var/log/app/application.log | grep --line-buffered "CRITICAL" | while read line; do
echo "ALERT: $line" | mail -s "Critical Error" qa-team@example.com
done
Подстановка процессов
Подстановка процессов позволяет использовать вывод команды так, как если бы это был файл:
# Сравнить вывод двух команд
diff <(curl -s https://staging.example.com/api/config) <(curl -s https://prod.example.com/api/config)
# Сравнить отсортированный вывод
diff <(sort file1.txt) <(sort file2.txt)
Практическое упражнение
- Используйте цепочку каналов для поиска 5 самых частых слов в текстовом файле
- Перенаправьте stdout и stderr тестового запуска в отдельные файлы
- Используйте
tail -fдля мониторинга лог-файла, запуская тесты в другом терминале - Постройте конвейер для анализа лога доступа: подсчитайте запросы по коду статуса, показав топ-5
- Используйте
teeдля сохранения вывода curl в файл с одновременной передачей через jq - Напишите однострочник, который находит все файлы
.spec.ts, содержащиеtest.only, и выводит их с номерами строк