Хвост рулонных файлов
У меня есть каталог с полными файлами журналов, которые я хотел бы использовать для хвоста.
Файлы называются таковыми:
name modified
00A.txt Dec 27 19:00
00B.txt Dec 27 19:01
00C.txt Dec 27 19:02
00D.txt Dec 27 19:03
В более старой системе unix я пытаюсь найти оболочку script, которая будет привязывать последний измененный файл в определенном каталоге, и если этот файл будет закрыт административно (перекатывается к следующему файлу), я хотите, чтобы программа автоматически начинала обрабатывать новый файл без необходимости выходить из хвоста для повторного запуска.
tail -100f `ls -t | head -1`
Желаемое поведение, учитывая имена файлов выше, будет выглядеть следующим образом:
./logtailer.sh
Затем script начнет хвост 00D.txt. Как только регистратор завершил запись в 00D.txt, а новый файл журнала теперь был назван 00E.txt, программа автоматически начнет обрабатывать этот файл.
Можно записать этот script, просмотрев вывод хвоста для текста "Файл с административным закрытием", а затем снова выполнив следующую команду.
tail -100f `ls -t | head -1`
Есть ли более элегантный способ сделать это, чем просмотр текста "файл административно закрыт"? Как я могу даже прочитать вывод хвоста за строкой в оболочке script?
Изменить: я должен объяснить, что флаг -F для хвоста не является вариантом для меня в этой системе. Он использует другую версию хвоста, которая не содержит эту функцию.
Версия ОС - Solaris 10
Ответы
Ответ 1
Вы можете использовать опцию -F
для tail
, которая подразумевает --follow=name --retry
.
На странице man
:
-F
The -F option implies the -f option, but tail will also check to see if the
file being followed has been renamed or rotated. The file is closed and
reopened when tail detects that the filename being read from has a new inode
number. The -F option is ignored if reading from standard input rather than
a file.
Ответ 2
вам может понадобиться inotify
, чтобы обнаружить создание нового файла, обходным путем для этого было бы продолжать опрос файловой системы при запуске хвоста в фоновом режиме:
#!/bin/bash
get_latest() {
local files=(*.log)
local latest=${files[${#files[@]}-1]}
echo "$latest"
[[ $latest == $1 ]]
}
run_tail() {
tail -c +0 -f "$1"
}
while true; do
while current=$(get_latest "$current"); do
sleep 1
done
[[ $pid ]] && kill $pid
run_tail "$current" & pid=$!
done
(непроверенный, небрежно взломанный и будьте осторожны с ограничениями вашей старой системы!)