Просмотр текстовых файлов и конвейеры
DevOps-инженер постоянно читает текст: конфиги, логи, вывод команд, .env-файлы, манифесты Kubernetes, результаты CI/CD. Большая часть диагностики начинается с простого вопроса: "что написано в файле или выводе команды?"
Для этого в Linux есть набор маленьких утилит. Каждая делает одну вещь хорошо, а вместе они собираются в мощные конвейеры.
Стандартный ввод, вывод и ошибки
У процесса в Linux есть три стандартных потока:
| Поток | Номер | Для чего |
|---|---|---|
| stdin | 0 |
стандартный ввод |
| stdout | 1 |
обычный вывод |
| stderr | 2 |
ошибки и диагностические сообщения |
Когда команда печатает результат в терминал, обычно это stdout. Когда команда ругается, это stderr.
Перенаправление:
command > out.txt # stdout в файл, файл перезаписывается
command >> out.txt # stdout в конец файла
command 2> errors.txt # stderr в файл
command > all.txt 2>&1 # stdout и stderr в один файл
command 2>/dev/null # выбросить ошибки
/dev/null - специальное устройство, которое "проглатывает" всё записанное. Его используют, когда вывод ошибок ожидаем и не нужен.
cat: вывести содержимое
cat читает файл и выводит его целиком:
cat /etc/hosts
cat /opt/devops/lab5/server.log
Для маленьких файлов это самый быстрый способ посмотреть содержимое. Для больших логов cat неудобен: он выведет тысячи строк и терминал быстро станет нечитаемым.
cat может объединять несколько файлов:
cat part1.txt part2.txt > combined.txt
Порядок аргументов важен: сначала выводится part1.txt, потом part2.txt. Перенаправление > записывает общий вывод в новый файл.
Нумерация строк:
cat -n /etc/nginx/nginx.conf
Это удобно, когда нужно обсудить конкретную строку конфига.
head и tail: начало и конец файла
head показывает начало файла:
head /var/log/syslog
head -n 5 /var/log/syslog
Без параметров head выводит первые 10 строк. Флаг -n задаёт точное количество строк.
tail показывает конец файла:
tail /var/log/syslog
tail -n 20 /var/log/syslog
Для логов конец часто важнее начала, потому что там самые свежие события.
Особый режим:
tail -f /var/log/syslog
tail -f остаётся запущенным и печатает новые строки по мере появления. Так смотрят логи в реальном времени: запускаешь команду, воспроизводишь проблему, смотришь, какие строки добавились. Чтобы выйти, нажми Ctrl+C.
Можно комбинировать head и tail. Например, получить строки с 11-й по 20-ю:
head -n 20 file.txt | tail -n 10
Сначала берём первые 20 строк, потом из них оставляем последние 10.
less: интерактивный просмотр
less открывает файл постранично:
less /var/log/syslog
Полезные клавиши:
| Клавиша | Действие |
|---|---|
Space |
страница вниз |
b |
страница вверх |
g |
в начало файла |
G |
в конец файла |
/text |
поиск по тексту |
n |
следующее совпадение |
q |
выйти |
Преимущество less перед cat: он не заливает терминал всем файлом сразу и позволяет спокойно искать нужные места. Для больших логов это стандартный инструмент просмотра.
wc: подсчёт строк, слов и байт
wc считает объём текста:
wc -l file.txt # строки
wc -w file.txt # слова
wc -c file.txt # байты
В диагностике чаще всего нужен wc -l. Он считает символы перевода строки, что для обычного текстового файла практически означает количество строк.
Примеры:
wc -l /opt/devops/lab5/server.log
grep "ERROR" /opt/devops/lab5/server.log | wc -l
Во втором примере grep сначала оставляет строки с ERROR, а wc -l считает, сколько таких строк получилось.
grep: поиск по содержимому
grep ищет строки, соответствующие шаблону:
grep "ERROR" /var/log/app.log
Если строка содержит ERROR, она будет выведена. Если не содержит, будет пропущена.
Частые флаги:
grep -i "error" app.log # без учёта регистра
grep -n "ERROR" app.log # с номерами строк
grep -v "INFO" app.log # строки, где нет INFO
grep -c "WARNING" app.log # только количество совпавших строк
grep -r "password" /etc/ # рекурсивный поиск по директории
grep -c "GET" file обычно даёт тот же счётчик, что и:
grep "GET" file | wc -l
Первый вариант короче и эффективнее, второй полезен как учебный пример конвейера.
Важно: grep ищет строки, а не отдельные "совпадения внутри строки". Если в одной строке слово ERROR встретилось три раза, grep -c ERROR file посчитает одну строку.
Регулярные выражения в grep
Шаблон grep может быть простой строкой, а может быть регулярным выражением.
grep "404" access.log
grep " 5[0-9][0-9] " access.log
Второй пример ищет HTTP-коды 500-599. Пробелы вокруг шаблона помогают не спутать код ответа с частью другого числа.
Расширенный режим -E включает более удобный синтаксис:
grep -E "(ERROR|CRITICAL)" app.log
Так можно найти строки, где есть ERROR или CRITICAL.
На старте не нужно знать все регулярные выражения. Достаточно понимать, что grep может фильтровать строки по тексту и по шаблону.
Конвейер: pipe
Конвейер | передаёт stdout одной команды на stdin следующей:
cat /var/log/nginx/access.log | grep "404" | wc -l
Эта команда выполняет три шага:
catвыводит файл.grep "404"оставляет только строки с404.wc -lсчитает количество оставшихся строк.
Часто cat в начале можно убрать:
grep "404" /var/log/nginx/access.log | wc -l
Это делает то же самое короче: grep сам умеет читать файл.
Главная идея pipe: каждая команда получает текст, преобразует его и передаёт дальше. Поэтому сложная обработка строится из маленьких понятных шагов.
sort и uniq: сортировка и уникальные строки
sort сортирует строки:
sort ips.txt
sort -r ips.txt # обратный порядок
sort -n numbers.txt # числовая сортировка
sort -rn counts.txt # числа по убыванию
uniq убирает соседние дубликаты:
uniq ips.txt
uniq -c ips.txt
Ключевое слово - соседние. Если одинаковые строки находятся в разных местах файла, uniq их не объединит. Поэтому стандартная связка такая:
sort ips.txt | uniq
Подсчитать повторы и отсортировать по убыванию:
sort ips.txt | uniq -c | sort -rn
Разбор:
sort ips.txtставит одинаковые строки рядом;uniq -cсчитает количество повторов;sort -rnсортирует числовой счётчик по убыванию.
awk: взять нужное поле
awk умеет обрабатывать текст по полям. По умолчанию поле - это часть строки, отделённая пробелами или табами.
awk '{print $1}' access.log
Разбор: awk читает файл построчно, программа в кавычках выполняется для каждой строки, print печатает значение, а $1 означает первое поле строки. $2 - второе поле, $NF - последнее поле, NF - количество полей.
В access.log первое поле часто является IP-адресом:
192.168.1.10 - - [12/May/2026:10:00:01 +0000] "GET / HTTP/1.1" 200 512
Команда:
awk '{print $1}' access.log
выведет:
192.168.1.10
Для статистики IP это соединяется с sort и uniq:
awk '{print $1}' access.log | sort | uniq -c | sort -rn
Как собирать pipeline без ошибок
Не пытайся сразу писать длинную команду вслепую. Собирай её постепенно.
Сначала проверь первый шаг:
awk '{print $1}' /opt/devops/lab6/access.log
Потом добавь сортировку:
awk '{print $1}' /opt/devops/lab6/access.log | sort
Потом подсчёт:
awk '{print $1}' /opt/devops/lab6/access.log | sort | uniq -c
И только затем финальную сортировку и запись в файл:
awk '{print $1}' /opt/devops/lab6/access.log | sort | uniq -c | sort -rn > /root/ip_stats.txt
Так проще найти ошибку: если результат сломался после добавления нового шага, проблема почти всегда в этом шаге.
Практический сценарий
Нужно понять, какие IP чаще всего получают 5xx ошибки в nginx:
grep " 5[0-9][0-9] " /var/log/nginx/access.log \
| awk '{print $1}' \
| sort \
| uniq -c \
| sort -rn \
| head -10
Шаги:
grep " 5[0-9][0-9] "оставляет строки с кодами 500-599.awk '{print $1}'берёт первое поле, обычно IP.sortгруппирует одинаковые IP рядом.uniq -cсчитает повторения.sort -rnсортирует по количеству по убыванию.head -10показывает топ-10.
Это типичный стиль Linux: не одна огромная программа, а цепочка маленьких инструментов, где каждый шаг можно проверить отдельно.
