python - 如何使用子进程和 Popen 从长时间运行的进程返回标准输出?

标签 python shell subprocess stdout

我正在使用 subprocess.Popen() 的一个非常基本的设置,并将 stdout 定向到一个变量,稍后我返回到我的 python 脚本的不同部分。

这是我的基本 Popen 代码:

process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# wait for the process to terminate
out, err = process.communicate()
errcode = process.returncode
print out

这适用于许多基本用例,如 ls -al 或类似的。但是,我想知道如何处理从较长(或无限期)运行的进程(例如 tail -f foo.log)中定期且一致地获取输出。有没有办法在循环中定期读取标准输出?或者产生一个线程来定期检查并返回每个线程?这里最好的方法是什么?

谢谢!

最佳答案

我认为重要的是要注意原始代码不正确(或者说不安全)。 它通常会工作,但在您给定的示例中没有任何内容等待进程退出。它可能仍在运行。

process.poll()process.wait() 是实现此目的的两个不错的选择。


当您不知道输出可能有多大时,communicate 是危险的,因为它会将输出缓冲到内存中,并可能使您耗尽内存。但是,如果您使用的是 subprocess.PIPE,则无论如何都可能发生这种情况。

您应该根据需要仔细选择 stdoutstderr 的目标。如果它可能非常大,写入磁盘上的文件可能是最佳选择。不过,这是一个单独的讨论。


要在不等待进程关闭的情况下查看输出,您应该在单独的线程中运行如下内容:

while process.returncode is None:
    # handle output by direct access to stdout and stderr
    for line in process.stdout:
        print line
    # set returncode if the process has exited
    process.poll()

我愿意就您应该如何实际访问文件对象 stdoutstderr 发表评论,但这是我临时想到的。

尽管这是处理派生子进程的最可靠方法,但如果可以的话,请认真考虑使用 process.wait() —— 它只会让一切变得更简单。

关于python - 如何使用子进程和 Popen 从长时间运行的进程返回标准输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22263283/

相关文章:

Python 写入映射文件 - 奇怪的行为

python - Pandas 多索引创建性能

regex - 是否有使用正则表达式更改文件名的 grep 或 shell 脚本?

linux - 是否可以在前台运行两个 Linux 命令并合并它们的标准输出

shell - 如何在 if 语句 .sh shell 中进行比较

python - 将标准输出子处理到文件,缺少新行

python - 使用 cmap 在 opencv 中保存 16 位图像(cv::ColorMap 仅支持函数 'operator()' 中 CV_8UC1 或 CV_8UC3 类型的源图像)

python - 如何在 python MySQLDB 中执行 SQL_CALC_FOUND_ROWS

python - subprocess.Popen 在做什么可能会导致 "Software caused connection abort"?

python - 将多个子进程的输出附加到Python中的数组