Иногда нужно просто наблюдать, как меняется значение: растёт ли число соединений, уезжает ли нагрузка, продвигается ли индексация. Запускать команду руками каждые десять секунд утомляет уже на пятой итерации, а разворачивать полноценный мониторинг ради десятиминутной диагностики нерационально. Утилита watch решает это элегантно: она выполняет указанную команду с фиксированным интервалом и отрисовывает её вывод на весь терминал, обновляя картинку. В статье разбираем практику: базовые приёмы, подсветка изменений, типовые метрики для наблюдения, тонкости экранирования и ограничения инструмента.

Базовые приёмы, интервал, диффы, форматирование

Простейший запуск это watch df -h: каждые две секунды показывается актуальная таблица файловых систем. Интервал меняется флагом -n число: watch -n 0.5 позволяет смотреть с subsecond-периодом, watch -n 60 обновляет картинку раз в минуту - для медленно меняющихся показчиков вроде заполнения диска секундная сетка только раздражает мерцанием.

Флаг -d подсвечивает различия между текущим и предыдущим выводом: при наблюдении за очередью задач или счётчиком соединений изменившиеся цифры вспыхивают, и глаз сразу ценит динамику, а не перечитывает весь экран. Управление есть и во время работы: пробел принудительно обновляет вывод, Ctrl+Z подвешивает, q выходит, по стандарту. Опция -t убирает заголовок с командой и временем, что полезно для встраивания в тайловые терминальные менеджеры, где заголовок уже есть у панели.

Флаги -x (exec без shell) и -p (precise, строгий интервал от начала запуска) встречаются в мелкой специфике: -x предотвращает неожиданную интерполяцию спецсимволов, а -p нужен там, где требуется строгая периодичность опросов без накопления задержки. По умолчанию период отсчитывается с учётом времени выполнения самой команды, и обычно это правильное поведение для мониторинга.

Типовые сценарии наблюдения под нагрузкой

Первая группа сценариев - ресурсы сервера. watch -n 1 free -m следит за памятью в мегабайтах по мере роста нагрузки, watch -n 1 'cat /proc/loadavg' показывает load average с интервалом в секунду, watch -d -n 2 'ss -s' ведёт агрегат открытых сокетов и выделяет изменения числа. Когда идёт нагрузочное тестирование и вы ждёте, в какой момент приложение начнёт деградировать, такие наблюдения заменяют тяжёлый мониторинговый стек.

Вторая группа - состояние сервисов: watch -n 2 'systemctl is-active myapp; systemctl show myapp -p NRestarts' следит за активностью и числом рестартов сервиса, а watch kubectl get pods -o wide в кластере показывает перекатки подов в реальном времени. Вспомогательный приём watch -n 5 'docker ps --format "table {{.Names}}\t{{.Status}}"' даёт компактную таблицу живых контейнеров с их аптаймом, и этот кадр быстро обнаруживает контейнер, который уходит в crashloop.

Третья группа - прогресс длительных операций: файловый перенос отражается в du -sh каталог-назначения каждые пять секунд и позволяет прикинуть темп копирования, балансировка Ceph или синхронизация mdadm видна через watch cat /proc/mdstat, и даже postgres-реплика смотрится через watch 'psql -c "select pg_last_wal_receive_lsn()"'. Общая идея: почти любая команда, печатающая текущее состояние, приобретает ценность наблюдения при помещении под watch.

Четвёртая группа - диагностика очередей и лимитов. Наблюдение watch -n 2 'cat /proc/net/sockstat' раскрывает число TCP-сокетов по типам и приближение к лимитам, watch ss -antp показывает полные сокеты с процессами, и на десятке тысяч соединений динамика становится наглядной. Ещё одна практичная связка: watch 'ls каталог-входа | wc -l' для папки, куда падают файлы на обработку; увидеть, что входной каталог стабилизировался, это знак того, что обработчик перестал поспевать.

Экранирование и составные команды, как не сломать пайп

/watch выполняет команду через shell, но спецсимволы требуют аккуратности. Пайп, редиректы, переменные - всё это надо закавычить целиком в одинарные кавычки: watch 'ls /data | wc -l' корректно, тогда как watch ls /data | wc -l внезапно работает не так: пайп относится уже к выводу watch, и wc будет считать строки вместо вас на каждый refresh. Это самая частая ошибка первых недель знакомства с утилитой.

Вторая ловушка - доллар и обратные кавычки: переменные окружения интерполируются вашим текущим shell один раз при запуске, а не при каждом выполнении, поэтому watch 'echo $HOME' напечатает постоянное значение; если нужно пересчитывать каждый раз - экранируйте как \$: watch 'echo \$((RANDOM))'. Третья мелочь - команды с опциями, начинающимися с дефиса: передаются внутри одинарных кавычек без экранов. И наконец, запуск скрипта, результат которого зависит от текущего каталога: watch -x в фиксированном каталоге будет вашим спасением, при сомнениях - абсолютные пути.

watch против полноценного мониторинга

Граница применимости проходит просто: watch работает на ближайшие минуты диагностики, а не на историю за месяц. Ни алертинга, ни демонстрации тренда за неделю, ни сложения многих хостов в одну картину там нет, и это правильно - инструменты сравниваются не по амбициям, а по времени от появления потребности до появления ответа. По этому критерию watch выигрывает всегда: три секунды, и вы уже смотрите нужную метрику.

Для случаев, когда watch уже близко к потолку, есть htop и подобные самодостаточные панели, а для истории и алертинга персонал и так встанет у руля Prometheus. Промежуточная ступень - записанные в bashrc короткие watch-шаблоны под свои типовые задачи: alias wload='watch -n 1 cat /proc/loadavg' и прочие. Постепенно набор превращается в личный набор шпионского оборудования, и диагностика становится почти непринуждённой.

Резюме на полях: watch не делает ничего, чего нельзя повторить руками, но снимает с вас необходимость эти руки прилагать, и в этом вся прелесть - ближайшие минуты диагностики перестают зависеть от везения, когда вызванная двадцать раз подряд команда наконец покажет тот самый момент, в который всё сломалось.
## Цвет, кодировка и чистота вывода внутри watch

Терминальные команды теряют раскраску вывода внутри watch, потому что программы видят, что stdout не настоящий терминал, и отключают ANSI. Лечится принудительным флагом цвета у самой команды, например ls --color=always; у watch есть и --color, который интерпретирует ANSI-последовательности, если команда их отдала. Для многострочных таблиц удобно явно держать ширину: watch 'ps aux --sort=-%cpu | head -20' держит хидер фиксированным и избавляет от разъезжающихся колонок.

Вторая тонкость - локаль: кириллица в именах файлов и подписей отображается корректно только при подходящей локали у терминала, поэтому для надёжности на серверах выставляют LANG=C.UTF-8 перед началом длинной сессии мониторинга. Эта мелочь избавляет от кракозябр в таблицах, за которыми предстоит наблюдать часами.

Сценарии из повседневной практики, проверенные временем

Первый сценарий - контроль перекатки релизов: во время деплоя открывается watch -n 1 'curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" https://app/health', и деградация проявляется падением кода раньше внешнего мониторинга - ваш взгляд уже на экране. Второй сценарий: миграция данных с прогрессом через watch 'du -sh /newdata; ls /newdata | wc -l' показывает и объём, и количество файлов; по соотношению между ними почти сразу понятно, не переписывает ли скрипт одно и то же десятки раз по кругу - такое встречается, и заметить это лучше рано.

Третий сценарий - наблюдение за распределением нагрузки: watch -n 1 'mpstat -P ALL 1 1' каждую секунду отрисовывает загрузку каждого ядра, и перекосы становятся видны сразу. Четвёртый: ожидание завершения длинной фоновой операции - watch с пятиминутным интервалом ловит появление нужной строки состояния, не отвлекая и не создавая лишней нагрузки.

Когда watch - плохая идея

Честности ради оговорим пределы. Команд с побочными эффектами внутри watch быть не должно: никаких запусков, меняющих состояние системы, иначе вы получите эффект каждые две секунды. Тяжёлые проверки с развёртыванием контекста - сложная выборка на проде раз в секунду или запрос в облачное API с rate limit - съедят ресурсы; watch нисколько не удешевляет саму команду, он лишь повторяет её. И последнее: watch это локальный инструмент. Как только возникает желание наблюдать за десятью серверами разом, пора открывать tmux с синхронизированными панелями или, что правильнее, полноценный мониторинговый стек, оставив watch его элегантную нишу короткой диагностики.

Хорошей завершающей привычкой будет добавить в bashrc один-единственный шаблон: alias w='watch -n 2 -d ', после которого наблюдение за любой командой превращается в набор слов w 'ваша команда' - и все приёмы из этой статьи применяются без раздумий, как и положено инструменту, занимающему три буквы в вашем rc-файле.
Связки с другими инструментами, от наблюдения к действию

watch редко живёт в одиночестве: его сила в том, что любая текстовая команда превращается в панель мониторинга. Системные метрики: watch -n 1 'ps_mem | tail -5' держит под рукой пятерку самых прожорливых процессов по памяти, watch -n 2 'docker stats --no-stream' показывает таблицу контейнеров с CPU и памятью без метания интерактивного режима. Логи: watch 'tail -20 /var/log/myapp.log' это минималистичный tail -f с паузой, который удобен, когда нужен срез последних строк, а не бегущая пелена.

Сетевые наблюдения: watch -n 2 'nft list ruleset | grep -c drop' следит за ростом счётчика отброшенных пакетов, watch 'ip -s link show eth0' показывает счётчики ошибок и потерь на интерфейсе с интервалом пересчёта. Дисковые: watch -n 5 'smartctl -a /dev/nvme0 | grep -E "Temperature|Percentage'". Звук странный, а даёт уверенность в том, что NVMe живёт в разумных температурах под нагрузкой.

И наконец, пара слов о совмещении watch с tmux: четырёхпанельный терминал с памятью, диском, сетью и процессами под watch в каждой панели это де-факто бесплатный дашборд 'всё сразу' для аварийной сессии на сервере, который требует ноль установки и ноль настройки. Дерзко просто, и именно поэтому незаменимо.
Мелочи последнего порядка

Ещё несколько полезных бит, не потянувших на отдельный раздел, но проверенных жизнью. Флаг -e (errexit) завершает watch, как только команда вернула ненулевой код: удобно ждать момента, когда сервис сломается или наоборот - поднимется, смотря какую сторону нуля вы ждёте. Параметр -g (chgexit) выходит при изменении вывода, и watch в ожидании конкретного события наконец-то может молчать, пока не случится что-то интересное. Комбинация с терминальным звонком позволяет переключиться на соседний экран и ждать известий по звуку, а не гипнотизировать терминал.

Для записи видео терминальной диагностической сессии всё это идеально снимается сторонними рекордерами терминала, но это уже сюжет соседнего рассказа. Пока достаточно простого наблюдения: инструмент возрастом в четверть века по-прежнему уделывает конкурентов по соотношению освоения к полезности, и эта пропорция в мире утилит исключительная.
И в качестве практического напутствия: начните с трёх сценариев - память через free -m, диски через df -h и сеть через ss -s. Через неделю эти командные строки будут срабатывать раньше, чем вы сформулируете вопрос, а это и есть верный признак инструмента, который встроился в работу. После этого можно смело расширять набор: очереди приложения, реплики баз, счётчики балансировщика - всё то, что в вашем окружении требует глаз чаще, чем дашборда.

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