2014-11-18 2 views
0

Я копирую LOGFILE на удаленный сервер по мере его создания.Как я могу сказать хвост, если он закончил - чисто?

tail -f LOGILE | gzip -c >> /faraway/log.gz 

Однако, когда оригинал LOGFILE закрыт, и перемещен в каталог хранения, мой хвост -f кажется, чтобы получить какие-то странные данные.

Как я могу гарантировать, что tail -f прекратит чистоту и что сжатый файл /faraway/log.gz является подлинной копией LOGFILE?

EDIT 1

я сделал немного больше рыть.

/faraway/log.gz завершено плохо - на полпути через сообщение FIX. Это должно быть из-за того, что я выполнил команду выше.

ЕСЛИ проигнорировать эту последнюю строку, тогда оригинальные LOGFILE и log.gz соответствуют ТОЧНО! Это для файла 40G, передаваемого по атлантическому.

Я очень впечатлен этим, поскольку он делает именно то, что я хочу. Кто-нибудь читатель думает, что я просто «повезло» в этом случае - разве это НЕ работает в будущем?

Теперь мне просто нужно получить чистое закрытие gzip. Возможно, отправка kill -9 в хвостовой PID, как предложено ниже, может позволить GZIP правильно завершить сжатие.

+0

Можете ли вы определить «странные данные» для этого случая? Также как LOGFILE «закрыт»? 'tail -f' будет продолжать чтение из файла, даже если вы' mv'. Вам нужно дать 'tail' по какой-то причине прекратить следовать за файлом. –

+2

Если вам нужна полная и полная копия файла, 'tail -f' является неправильным инструментом для задания, все-stop. Если вы не гарантируете, что он пуст, когда вы начнете процесс, вы даже не можете поймать начало - и если ваша реализация 'gunzip' не будет построена с ожиданием перезагрузки потока сжатия, вы получите сюрпризы там тоже. –

+0

@EtanReisner Кажется, что одна или две строки отсутствуют. Я убиваю процесс с помощью ctrl-c, как только LOGFILE был перемещен. Мне нужно послать tail -f сигнал, чтобы сказать, что LOGFILE закончен - пусть gzip крупным планом. – ManInMoon

ответ

0

Чтобы получить полную копию, используйте

tail -n +1 -f your file 

Если ваш не использовать -n +1 вариант, вы получите только хвостовая часть файла.

Однако это не решает проблему с удаленным/перемещенным файлом. Фактически проблема удаления/перемещения файла связана с проблемой IPC (межпроцессная связь) или с проблемой взаимодействия между процессами. Если у вас нет правильной модели поведения других процессов, вы не можете решить проблему.

Например, если другая программа КОПИРУЕТ файл журнала в другом месте, а затем удаляет текущий, а программа записывает выходные данные в этот новый файл журнала ... По-видимому, ваш хвост не может читать эти выходы.

Связанная особенность UNIX (и Unix-подобные системы) на сумму упоминанием:

Когда файл открыт для чтения с помощью процесса А, а затем удален процесса B, физическое содержание будет не должен быть немедленно удален, , поскольку его счетчик ссылок не равен нулю (кто-то все еще использует его, т.е. процесс A). Процесс A все равно может получить доступ к файлу, пока он не закроет файл . Перемещение файла - это еще один вопрос: если процесс B, скажем, перемещает файл в ту же физическую файловую систему (Примечание: в вашей системе может быть много физической файловой системы ), процесс A может все же получить доступ к файлу, даже файл растет. Этот вид перемещения - это , чтобы изменить имя (имя пути + имя файла), не более того. Идентификатор файла файла (a.k.a. «i-node» в unix) не изменяется. Тем не менее, , если файл перемещен в другую физическую файловую систему, локальную или удаленную, это как если бы файл был скопирован и удален. Таким образом можно применить правило удаления .

Проблема с недостающими линиями, о которой вы упомянули, интересна и может потребоваться больше анализа поведения программ/процессов, которые генерируют и перемещают/удаляют файл журнала.

--update--

Рад видеть вас есть некоторый прогресс. Как я уже сказал, процесс, подобный tail, по-прежнему может обращаться к данным после , файл удаляется в unix-подобной системе.

Вы можете использовать (echo $ BASHPID>/tmp/PID_tail; exec tail -n + 1 -f yourLogFile) | GZIP -с -> yourZipFile.gz

для GZIP файла журнала, и убить программу tail по

kill -TERM `cat /tmp/PID_tail` 

gzip должен закончить сам по себе без ошибок. Даже если вы беспокоитесь о том, что gzip получит сломанный сигнал трубы, вы можете использовать этот альтернативный способ предотвратить от сломанной трубы:

( (echo $BASHPID > /tmp/PID_tail; exec tail -n + 1 -f yourLogFile) ; true) | gzip -c - > yourZipFile.gz 

Разбитая труба защищена с помощью true, который не печатает ничего, но заканчивается.

+0

Предполагая, что вы используете bash, чтобы получить PID хвоста, который нужно убить (отправить сигналы), используйте '(echo $ BASHPID>/tmp/PID_tail; tail -n + 1 -f ваш файл) | gzip ... ' –

+0

(ссылаясь на приведенный выше комментарий): это будет работать, если вы запустили' exec tail -n + 1'; в противном случае вы зависите от оптимизации, которая может быть или не быть. (Вы знаете, какая версия bash автоматически «exec» в последнем компоненте подоболочки была добавлена?) –

+0

(ссылаясь на приведенный выше комментарий): не совсем уверен, что вы имеете в виду ... '(echo $ BASHPID> .. ., хвост ...) | gzip ... & 'наверняка откроет два процесса, по одному для каждой стороны вокруг' | '. Внутри подоболочки '(...; ...)' ''; 'будет означать, что две части исполняются в одной и той же под-оболочке, так как она должна выполняться последовательно. –

Смежные вопросы