Python - 运行进程并等待输出

Posted

技术标签:

【中文标题】Python - 运行进程并等待输出【英文标题】:Python - Run process and wait for output 【发布时间】:2018-11-19 00:51:24 【问题描述】:

我想运行一个程序,等待它的输出,向它发送输入并重复直到出现条件。

我能找到的只是关于等待程序完成的问题,事实并非如此。该过程仍将运行,只是不会提供任何(新)输出。

程序输出在标准输出和日志文件中,都可以使用。 使用 linux。

到目前为止的代码:

import subprocess

flag = True
vsim = subprocess.popen(['./run_vsim'], 
                        stdin=subprocess.pipe,
                        shell=true, 
                        cwd='path/to/program')
while flag:
    with open(log_file), 'r') as f:
        for l in f:
            if condition:
                break
    vsim.stdin.write(b'do something\n')
    vsim.stdin.flush()
vsim.stdin.write(b'do something else\n')
vsim.stdin.flush()

事实上,即使在程序完成启动之前,“做某事”输入也会被多次发送。此外,在程序完成运行最后一次 while 迭代的命令之前读取日志文件。这会导致它缓冲输入,因此即使在满足条件后我也会继续执行命令。

我可以在每个stdin.write 之后使用time.sleep,但由于执行每个命令所需的时间是可变的,我需要使用比必要时间更长的时间,从而使 python 脚本变慢。此外,这是一个愚蠢的解决方案。

谢谢!

【问题讨论】:

子进程是否打印某种标准的“完成”消息,表明它已完成处理?如果是这样,您可能可以使用pexpect 你考虑过threading, multiprocessing,还是asyncio? 进程是将数据转储到管道还是将其运球 - 当您获得数据时,您如何知道您已获得所有数据?你是说进程永远不会终止吗? @Linuxios 我不知道,但我会调查一下。 @wwii 我没有,但我会阅读文档。我很确定它是多线程的,如果不是,python 脚本会等待子进程运行(我可能是错的,以前从未使用过线程) 【参考方案1】:

如果您使用的是 python3,您可以尝试更新您的代码以改用subprocess.run。它应该等待您的任务完成并返回输出。

【讨论】:

就像我在问题中所说的,任务进程仍在运行,它只是没有提供任何新的输出,因为它正在等待输入。【参考方案2】:

截至2019年,您可以使用subprocess.getstatusoutput()运行一个进程并等待输出,即:

import subprocess
args = "echo 'Sleep for 5 seconds' && sleep 5"
status_output = subprocess.getstatusoutput(args)
if status_output[0] == 0: # exitcode 0 means NO error
  print("Ok:", status_output[1])
else:
  print("Error:", status_output[1])

Python Demo


来自pythondocs:

subprocess.getstatusoutput(_cmd_)

返回 (exitcode, output) 在 shell 中执行 cmd

在带有Popen.check_output() 的shell 中执行字符串cmd 并返回一个2 元组(exitcode, output)。使用区域设置编码;有关详细信息,请参阅Frequently Used Arguments 上的注释。

从输出中删除尾随换行符。该命令的退出代码可以解释为子进程的返回代码。示例:

>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> subprocess.getstatusoutput('cat /bin/junk')
(1, 'cat: /bin/junk: No such file or directory')
>>> subprocess.getstatusoutput('/bin/junk')
(127, 'sh: /bin/junk: not found')
>>> subprocess.getstatusoutput('/bin/kill $$')
(-15, '')

【讨论】:

【参考方案3】:

您可以使用命令而不是子进程。以下是 ls 命令的示例:

import commands 
status_output = commands.getstatusoutput('ls ./')
print status_output[0] #this will print the return code (0 if everything is fine)
print status_output[1] #this will print the output (list the content of the current directory)

【讨论】:

来自文档:自 2.6 版起已弃用:命令模块已在 Python 3 中删除。改用 subprocess 模块。问题有 python-3x 标签 它有python标签

以上是关于Python - 运行进程并等待输出的主要内容,如果未能解决你的问题,请参考以下文章

python之 启动一个子进程并等待其结束

Python - 调用 perl 作为子进程 - 等待完成其后台进程并打印到 shell

子进程 readline 挂起等待 EOF

使用管道进行Python进程输入/输出

python多处理池,等待进程并重启自定义进程

python 怎么启动一个外部命令程序,并且不阻塞当前进程