Как устроен tail и что добавляет -f
Без ключей tail выводит последние десять строк файла и завершается. Это удобно для быстрого взгляда на конец журнала, но неудобно, если записи ещё поступают: пока вы набирали команду второй раз, появилось новое событие.
Ключ -f (от follow) говорит: напечатай конец файла и не завершайся, а ожидай новых данных и выводи их по мере дописывания. Терминал «зависает» в ожидании, и это нормально. Остановить слежение можно сочетанием Ctrl+C.
Типичный сценарий — диагностика сети. Вы запускаете tail -f на файле журнала, затем на другой вкладке выполняете действие, которое нужно проверить: пытаетесь подключиться, перезапускаете службу, отправляете запрос. Новые строки появляются в первой вкладке сразу в момент события, и причинно-следственная связь видна прямо на экране, без поиска нужной минуты в большом файле.
Ключи tail, которые используют чаще всего
Для работы с журналами хватает небольшого набора ключей.
| Команда | Результат |
|---|---|
| tail файл | последние 10 строк |
| tail -n 50 файл | последние 50 строк |
| tail -n +2 файл | всё, начиная со второй строки |
| tail -f файл | конец файла и слежение за новыми строками |
| tail -F файл | слежение по имени, переживает ротацию |
| tail -f файл1 файл2 | слежение сразу за двумя файлами |
При слежении за несколькими файлами tail перед каждой порцией печатает заголовок с именем файла, так что источник строки понятен. Форма tail -n +2 пригодится не для журналов, а для вывода с заголовком: она пропускает первую строку.
Ключи -n и -f комбинируются: tail -n 100 -f файл сначала показывает сто последних строк, а затем следит за новыми. Число строк пишут как отдельный аргумент или слитно, оба варианта обычно принимаются, но короткая форма вида tail -100 считается устаревшей.
Журнал ротируется: tail -f или tail -F
Большие журналы не растут бесконечно. Системные средства периодически переименовывают текущий файл, например в имя с суффиксом .1, и создают на его месте новый пустой файл. Это называется ротацией.
Ключ -f следит за открытым файлом, а не за именем. После ротации он продолжает читать старый переименованный файл, куда уже ничего не пишут, и вывод просто замирает. Выглядит так, будто в системе тишина, хотя события идут в новый файл.
Ключ -F отслеживает имя: если файл переименован или заменён, tail открывает файл заново и продолжает вывод с нового. Если файла пока нет, -F будет ждать его появления и сообщит об этом. Поэтому для долгих наблюдений и для сервисов, журналы которых ротируются, чаще берут -F. Ключ есть и в GNU-версии, и в версии tail из macOS.
Если файл просто не двигается, не спешите делать вывод о ротации: сначала убедитесь, что служба действительно пишет в этот файл и что у вас есть права на чтение.
Фильтрация потока: tail -f вместе с grep
Журнал занят множеством событий, а нужны только некоторые. Поток можно пропустить через grep: tail -F файл | grep -i 'timeout'. Однако при такой связке иногда кажется, что grep молчит. Причина в буферизации: когда вывод идёт не на терминал, а в конвейер, программа накапливает данные блоками и сбрасывает их, когда блок заполнится.
Чтобы строки появлялись сразу, у grep есть ключ --line-buffered: tail -F файл | grep --line-buffered 'timeout'. Он есть и в GNU-версии, и в версии grep для macOS. Если после grep в цепочке стоит ещё одна команда, ей тоже может понадобиться построчная выдача, иначе задержка вернётся.
Полезные комбинации:
- tail -F файл | grep -v 'debug' — убрать шумные записи.
- tail -F файл | grep -E 'error|warn' — показать только ошибки и предупреждения.
- tail -F файл | tee копия.txt — одновременно видеть поток и сохранять его, подробности на странице про tee.
Слово в шаблоне зависит от формата журнала: уровень записи может называться ERROR, error, err или иначе, поэтому полезно один раз посмотреть реальные строки и подобрать шаблон под них.
Где искать журналы и чем заменить tail
Расположение журналов определяет система и программа. В дистрибутивах семейства Debian общий системный журнал часто находится в /var/log/syslog, в других дистрибутивах его могут вести иначе, а многие службы пишут в собственные каталоги внутри /var/log. Прав обычного пользователя на чтение нужных файлов может не хватать, тогда команду запускают с sudo.
В системах с systemd журнал ведётся в двоичном виде, и вместо tail -f используют journalctl -f: он тоже следит за новыми записями. Для конкретной службы добавляют ключ -u с её названием. В macOS для потока системных сообщений есть команда log stream, а файлы журналов приложений лежат в каталогах Library/Logs.
Сетевые утилиты вроде ping и traceroute собственных журналов не ведут, но их вывод можно направить в файл и следить за ним через tail -f. Так делают, когда проверка идёт долго, а смотреть на неё постоянно не нужно: запустили в фоне, записали в файл, открываете конец по мере необходимости. Если строки в файле появляются с задержкой, причиной может быть буферизация вывода программы. Для сохранения вывода ping на Windows есть отдельная страница про запись в файл с отметками времени.
Порядок действий при проверке события
Чтобы слежение за журналом дало ответ, а не груду строк, действуйте по плану.
- Определите файл или источник, куда должна попасть запись о событии, и проверьте, что вы можете его прочитать.
- Откройте вторую вкладку терминала и запустите там tail -F с нужным файлом. Если журнал шумный, сразу добавьте grep с запасом: лучше увидеть лишнее, чем пропустить нужное.
- Выполните в первой вкладке действие, которое проверяете: подключение, перезапуск, запрос.
- Запомните время и первые строки, появившиеся сразу после действия. Строки, пришедшие минутой раньше, к вашему действию отношения не имеют.
- Остановите слежение через Ctrl+C и при необходимости сохраните найденные строки в файл для обращения в поддержку.
Если после действия в журнале ничего не появилось, возможны три причины: служба пишет в другой файл, уровень детализации журнала слишком низкий, либо событие не дошло до этой машины. Какая из них верна, подскажут настройки самой службы, поэтому в таком случае открывайте её документацию, а не гадайте по косвенным признакам.