Как работает параметр «-f» команды tail?

59
$ tail -f testfile

команда должна показывать последние записи в указанном файле в реальном времени, верно? Но этого не происходит. Пожалуйста, поправьте меня, если то, что я намерен сделать, неправильно ...

Я создал новый файл "aaa", добавил строку текста и закрыл ее. Затем выполните эту команду (первая строка):

$ tail -f aaa
xxx
xxa
axx

последние три строки - содержимое файла aaa. Теперь, когда команда все еще выполняется (так как я использовал -f), я открыл файл aaa через графический интерфейс и начал добавлять еще несколько строк вручную. Но терминал не показывает новые строки, добавленные в файл.

Что здесь не так? Команда tail -fтолько показывает новые записи, если они написаны только системой? (например, файлы журналов и т. д.)

это я
источник

Ответы:

62

Со tail(1) страницы руководства :

   With  --follow  (-f),  tail  defaults to following the file descriptor,
   which means that even if a tail’ed file is renamed, tail will  continue
   to  track  its  end.   This  default behavior is not desirable when you
   really want to track the actual name of the file, not the file descrip-
   tor (e.g., log rotation).  Use --follow=name in that case.  That causes
   tail to track the named file  in  a  way  that  accommodates  renaming,
   removal and creation.

Ваш текстовый редактор переименовывает или удаляет исходный файл и сохраняет новый файл под тем же именем файла. Используйте -Fвместо этого.

Игнасио Васкес-Абрамс
источник
работал! Итак, я могу использовать $ tail -F filenameкоманду все время вместо $ tail -f filenameправа?
its_me
17
Если это ваше намерение. Там могут быть случаи , когда вы хотите следовать за дескриптором вместо имени файла, но чтобы быть справедливым , я не встречал многих из них.
Игнасио Васкес-Абрамс
lsofможет показать, что это происходит - например lsof -Fpcftni, показало бы, что индекс, за которым следует индекс, tailбольше не тот, который открыт в редакторе.
Аарон Д. Мараско
10

Ваш редактор имеет свой собственный буфер для файла. Когда вы изменяете текст в редакторе, в сам файл ничего не записывается.

Когда вы сохраняете свои изменения, скорее всего, редактор просто удаляет старый файл и создает новый. tail -fбудет по-прежнему подключен к удаленному файлу, поэтому ничего нового не отобразится.

Стефан Хименес
источник
1
Редактор перезаписывает файл, в журналы добавляется текст. Это может быть проблемой.
Руфо Эль Магуфо
@Juan: я не понимаю ваш комментарий. «Перезаписать» не имеет конкретного значения, за исключением того, которое я описал в своем ответе.
Стефан Гименес
Да, я имел в виду то же самое, что и вы :)
Руфо Эль Магуфо
3

tail «обновлять» каждую 1 секунду по умолчанию, а не в реальном времени.

Попробуйте с этим (вам нужен bash4):

  • Откройте 2 терминала.
  • В первом терминале выполните touch ~/output.txtи tail -f ~/output.txt.
  • Во втором терминале выполните for i in {0..100}; do sleep 2; echo $i >> ~/output.txt ; done
  • Посмотрите на вывод tail в первом терминале.
Руфо Эль Магуфо
источник
Вы имели в виду echo $i >> ~/output.txt? Кроме того, этот ответ не соответствует сути вопроса.
Игнасио Васкес-Абрамс
1
Да, я исправил ошибку, когда вы написали комментарий :). Мой ответ - только проверка проблемы. Команда tail -f показывает новые записи, только если они записаны только системой?
Руфо Эль Магуфо
4
@Juan: В настоящее время в Linux tailfесть реализация на основе inotify. Так что он будет обновляться в режиме реального времени.
Стефан Гименес
Да tailf, но tailиспользует inotify ?. Я не знал tailf. На man-странице tail показано значение по умолчанию 1 секунда для -s.
Руфо Эль Магуфо
3
Да, tailза ним следуют и теперь используют inotify тоже, когда доступно. tailfвообще не опрашивает, просто спит, когда нет активности над файлом. tail -fпоказывает некоторую активность (см. straceвывод).
Стефан Гименес