【问题标题】:Python, subprocess, pipe and selectPython、子进程、管道和选择
【发布时间】:2015-10-24 12:06:44
【问题描述】:

我有一个 python 程序,我在其中不断读取通过 subprocess.Popen 启动并通过 subprocess.PIPE 连接的其他程序的输出

我面临的问题是它有时会丢失已启动程序的大部分输出。

例如,通过管道监控到 inotifywait 的 inotify 事件会丢失许多事件。

这是相关函数:

进程 = subprocess.Popen(["inotifywait", "-q", "-r", "-m", "--format", "%e:::::%w%f", srcroot], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 轮询 = select.poll() polling.register(process.stdout) process.stdout.flush() 而真: process.stdout.flush() 如果 polling.poll(max_seconds*1000): line = process.stdout.readline() 如果长度(线)> 0: 打印行[:-1]

执行命令inotifywait -q -r -m --format %e:::::%w%f /opt/fileserver/ > /tmp/log1 并移动一些文件(以生成inotify 事件)给出>8000 行文件。另一方面,使用我的./pscript.py > /tmp/log2 给出一个大约 5000 行的文件。

【问题讨论】:

  • 尝试从 stderr 获取线路,然后打印,检查丢失的数据是否真的存在。 - print process.stderr.read()
  • 不幸的是,上面的示例有些简化,因为我已经在检查 stderr。还是谢谢你。

标签: python inotifywait


【解决方案1】:

您在示例中完全忽略了 stderr。尝试像这样创建流程:

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

此外,我会直接将 inotify 与它的一个 Python bindings 一起使用,而不是使用 inotifywait 生成一个进程。

【讨论】:

  • 不幸的是,上面的示例有些简化,因为我已经在检查 stderr。此外,由于性能缓慢,我无法使用 pyinotify(我试过了,几千个文件都可以,但在我的情况下,它甚至无法创建足够数量的手表)......无论如何,谢谢。
  • 您不必设置成千上万的手表。您为每个要监视的文件夹设置一个监视,应用程序将调用您的回调。如果您还需要监视子文件夹,则只需在创建监视时指定它即可。
  • 在高层,是的。但在低级别,pyinotify 需要为任何不同的文件/目录建立一个监视。这个过程非常耗时,并且存在显着的可扩展性问题。纯 C 实现要快得多,主要是因为所有代码都已编译。
猜你喜欢
  • 2011-04-05
  • 1970-01-01
  • 2017-03-10
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 2019-12-01
  • 2018-08-04
相关资源
最近更新 更多