
предположим, что если скрипт оболочки добавляет данные в файл file.txt, например
1...........
2...........
3.............
4.............
5..............
Теперь мне нужен еще один скрипт, который мог бы проверять свежие данные, добавленные в file.txt, в течение пяти секунд, а не полные данные.
Я не знаю, есть ли какой-либо вариант, tail -f
показывающий полные данные.
для понимания чего-то вроде того, tail -5 file.txt
где -5 - это не количество строк, а количество секунд.
ПРИМЕЧАНИЕ: Я не хочу пропускать какие-либо данные каждый раз, когда мне нужно возвращать данные с того места, на котором они остановились в прошлый раз. Это важно.
решение1
retail
этос сохранением состояния tail
. Он записывает номер инода и размер файла после каждого вызова, следующий вызов продолжает с того места, где остановился (опционально работая и с повернутыми файлами, поэтому и записывается инод).
while true; do
retail myfile.log
sleep 5
done
Если только сами данные файла не содержат временных меток (это может быть, если они получены через syslog) или некоего монотонно увеличивающегося идентификатора, у вас должно быть какое-то внешнее состояние, retail
использующее размер файла.
Если предположить, что файл только добавляется и очищается построчно, то retail
данные не будут потеряны. Это также должно быть более надежным, чем проверка временных меток в данных, если только они не имеют высокой точности (например, мкс или выше).
retail
написан на C и, похоже, похож на предложение @Ulrich Dangel о logtail
. Похоже, есть две разные версии этого, обе реализованы на Perl, ни одну из которых я не использовал:
решение2
Вы можете извлечь последние 5линиииз скрипта, tail -n 5
но только последнее изменение в файле всегда имеет временную метку, нет временной метки для каждого изменения. Если вы хотите получить последнийнсекунд, вы должны хранить их отдельно сами.
Вы могли бы количественно оценить свои данные. Допустим, написание скрипта делает, в основном цикле создает функцию, которая будет запускаться раз в секунду:
CSEC=`date +%S`
if [ "x$CSEC" != "x$SAVEDSEC" ] ; then
mv f4.txt f5.txt
mv f3.txt f4.txt
mv f2.txt f3.txt
mv f1.txt f2.txt
echo $BUFFER > f1.txt
BUFFER=
SAVEDSEC=$CSEC
fi
и в месте, где он записывает данные, например, с помощью echo
, он также добавляет их в буфер.
echo $DATA >file.txt
BUFFER=$BUFFER$DATA
(и записи сохраняются в $BUFFER, а не записываются в 'file.txt`)
В этом случае ваш скрипт может cat f?.txt
извлечь последние 5 секунд данных.
Конечно, обратите внимание на блокировку. Если один скрипт считывает данные прямо во время дисковой операции другого скрипта, данные будут повреждены.
решение3
Это должно сделать именно то, что вам нужно...
#!/bin/bash
#This is the file we want to capture data from
TAILFILE=/path/to/input.txt
#This is the file we want to append to
OUTFILE=/path/to/output.txt
#How many seconds we want to tail the file
SECONDS=5
tail -F $TAILFILE >> $OUTFILE &
PID=$!
sleep $SECONDS
kill $PID