2015-08-02 3 views
1

У меня есть программа питона, где я постоянно читать вывод другой программы, запущенные с помощью subprocess.Popen и подключенной через subprocess.PIPEPython, подпроцесс, труба и выберите

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

Например, монитор для событий inotify через трубу до inotifywait теряет много событий.

Это соответствующие функции:

 

    process = subprocess.Popen(["inotifywait", "-q", "-r", "-m", 
     "--format", "%e:::::%w%f", srcroot], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    polling = select.poll() 
    polling.register(process.stdout) 
    process.stdout.flush() 

    while True: 
     process.stdout.flush() 
     if polling.poll(max_seconds*1000): 
      line = process.stdout.readline() 
      if len(line) > 0: 
       print line[:-1] 

Выполнение команды inotifywait -q -r -m --format %e:::::%w%f /opt/fileserver/ > /tmp/log1 и перемещение какой-либо файл вокруг (генерировать Inotify события) дают файл> 8000 строк. С другой стороны, используя мой ./pscript.py > /tmp/log2, вы получите файл с 5000 строк.

+0

Попробуйте получить строку от stderr, а также распечатайте это, проверьте, действительно ли потерянные данные там. - 'print process.stderr.read()' –

+0

К сожалению, приведенный выше пример был несколько упрощен, так как я уже проверял stderr. В любом случае, спасибо. – shodanshok

ответ

0

Вы игнорируете stderr полностью в своем примере. Попробуйте создать процесс, как это:

process = subprocess.Popen(["inotifywait", "-q", "-r", "-m", 
    "--format", "%e:::::%w%f", srcroot], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

Кроме того, я хотел бы использовать Inotify непосредственно с одним из его Python bindings, а не порождая процесс с inotifywait.

+0

К сожалению, приведенный выше пример был несколько упрощен, так как я уже проверял stderr. Более того, я не могу использовать pyinotify из-за его медленной производительности (я пробовал это, и это нормально для нескольких тысяч файлов, но в моем случае он даже не может создать достаточное количество часов) ... Спасибо вам все равно. – shodanshok

+0

Вам не нужно устанавливать тысячи часов. Вы устанавливаете часы для каждой папки, которую хотите контролировать, и приложение будет вызывать ваш обратный вызов. Если вам нужно смотреть вложенные папки, вам просто нужно указать его при создании часов. – noxdafox

+0

На высоком уровне, да. Но на низком уровне pyinotify необходимо установить часы для любого другого файла/каталога. Этот процесс занимает много времени, и он имеет значительные проблемы с масштабируемостью. Реализация чистого C выполняется намного быстрее, главным образом потому, что весь код скомпилирован. – shodanshok