LINUX.ORG.RU

Ответ на: комментарий от baverman

Это всего лишь рабочий вариант кода, предложенного ТС. Спасибо за полезный и содержательный ответ! :)

age
()

А вообще, чтоб получить tail-подобное поведение, нужно отслеживать изменения в файле и перечитывать. Только что смотрел код tail из coreutils - он использует inotify, либо какой-то свой велосипед если inotify отсутствует.

age
()
Ответ на: комментарий от age

ТС хотел tail -f, свой нерабочий пример он бы и так до ума довел.

baverman ★★★
()
Ответ на: комментарий от age

Думал есть какое-то более простое решение, чем inotify или мотаться в бесконечном цикле и ждать непустой строчки.

tx
() автор топика
Ответ на: комментарий от age

Всё равно не понимаю, как это сделать красиво. Файл прочитался до EOF, чтобы понять что там что-то добавилось, надо его перечитать заново, целиком. Некрасиво же.

tx
() автор топика
Ответ на: комментарий от tarc

Решение age тоже не работает (как tail -f), так что не волнуйтесь.

baverman ★★★
()
Ответ на: комментарий от tx
# -*- coding: utf-8 -*-
FILE = '/var/log/messages.log'

file = File.new(FILE, mode="r")
size = file.size
# зафейленные попытки прочитать последние n строк файла. лень.
# puts size.to_s
# file.lineno = (file.lineno - 10)
# 1.upto(10) { puts file.readline }
while true
  nsize = file.size
  if nsize > size then # размер файла вырос - значит в него дописали
    file.seek(size, IO::SEEK_SET) # пробегаем до начала добавленной части
    puts file.read # читаем все, что добавилось - до конца
    size = nsize
  end
  sleep(0.5)
end

ВНЕЗАПНО, если файл меняется, пока открыт еще где-то - переоткрывать и перечитывать его не надо.

age
()

Да, кстати, почему ты решил, что чтение со стандартного ввода будет блокировать вывод с другой стороны?

baverman ★★★
()
Ответ на: комментарий от baverman

То есть, что помешает процессу, сбрасывающего твоему тейлу поток, этот самый поток закрыть?

baverman ★★★
()
Ответ на: комментарий от age

> Я имел в виду первое решение, которое просто читает stdin.

Я тоже.

А смысл? Зачем такое вообще пайпить?

Не знаю. Это вопрос к ТСу :)

tarc
()
Ответ на: комментарий от age
import time, sys

f = open(sys.argv[1], 'rb')

while True:
    pos = f.tell()
    data = f.read(1024)
    if data:
        sys.stdout.write(data)
    else:
        time.sleep(1)
        f.seek(pos)

Но опять таки это не работает если файл обрезать.

baverman ★★★
()
Ответ на: комментарий от baverman

Зачем все эти костыли если есть inotify? Кросплатформенность?

true_admin ★★★★★
()
Ответ на: комментарий от baverman

Можно периодически сикать на конец

да просто stat() вызывать и смотреть не изменился ли размер.

true_admin ★★★★★
()
Ответ на: комментарий от age

Файл точно есть, специально исправил то что в примере на реально существующий.

ruby 1.8.7 (2009-04-08 patchlevel 160) [i386-freebsd7]

tx
() автор топика
Ответ на: комментарий от tx

_>

--- tail.rb	2010-11-27 23:10:41.713335839 +0200
+++ tail-1.8.rb	2010-11-27 23:10:33.726669174 +0200
@@ -2,14 +2,14 @@
 FILE = '/var/log/messages.log'
 
 file = File.new(FILE, mode="r")
-size = file.size
+size = file.stat.size
 # зафейленные попытки прочитать последние n строк файла. лень.
 # puts size.to_s
 # file.lineno = (file.lineno - 10)
 # 1.upto(10) { puts file.readline }
 puts file.inspect
 while true
-  nsize = file.size
+  nsize = file.stat.size
   if nsize > size then
     file.seek(size, IO::SEEK_SET)
     puts file.read
age
()
Ответ на: комментарий от age

Спс, даже что-то тейлится. Вопрос закрыт.

tx
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.