Python popen命令。等待命令完成


79

我有一个脚本,可通过popen shell命令启动。问题在于脚本不会等到该popen命令完成后才继续运行。

om_points = os.popen(command, "w")
.....

如何告诉我的Python脚本等待shell命令完成?

Answers:


110

根据您想如何使用脚本,您有两种选择。如果您希望命令阻塞并且在执行时不执行任何操作,则可以使用subprocess.call

#start and block until done
subprocess.call([data["om_points"], ">", diz['d']+"/points.xml"])

如果您想在执行过程中执行操作或将内容输入stdin,可以communicatepopen调用后使用。

#start and process things, then wait
p = subprocess.Popen([data["om_points"], ">", diz['d']+"/points.xml"])
print "Happens while running"
p.communicate() #now wait plus that you can send commands to process

如文档中所述,wait可能会死锁,因此建议进行通信。


检查出的文档subprocess.call
thornomad

虽然在许多答案中都首选子进程,但是它不能很好地处理命令中的空间和配额。上面的答案不能直接解决os.popen问题。


subprocess.run()是在Python 3.5中添加的,并且是“建议的调用子流程的方法”
LoMaPh

29

您可以subprocess用来实现这一目标。

import subprocess

#This command could have multiple commands separated by a new line \n
some_command = "export PATH=$PATH://server.sample.mo/app/bin \n customupload abc.txt"

p = subprocess.Popen(some_command, stdout=subprocess.PIPE, shell=True)

(output, err) = p.communicate()  

#This makes the wait possible
p_status = p.wait()

#This will give you the output of the command being executed
print "Command output: " + output

子进程的速度可能比操作系统慢2倍-bugs.python.org/issue37790
MonsieurBeilto

12

强制popen直到执行以下操作读取所有输出后,才能继续:

os.popen(command).read()

2
我不是python专家,但这似乎是对原始代码进行最少修改的最简单的解决方案。为什么这不是一个好的解决方案?
jdmcnair

6

让您尝试传递的命令为

os.system('x')

然后你把它隐瞒了

t = os.system('x')

现在python将等待命令行的输出,以便将它分配给变量t


4

您正在寻找的是wait方法。


但是,如果我输入:om_points = os.popen(data [“ om_points”] +“>” + diz ['d'] +“ / points.xml”,“ w”)。wait(),则会收到此错误:Traceback (最近一次通话最近):文件“ ./model_job.py”,第77行,在<module>中,om_points = os.popen(data [“ om_points”] +“>” + diz ['d'] +“ / points .xml”,“ w”)。wait()AttributeError:“文件”对象没有属性“等待”是什么问题?再次感谢。
米歇尔2010年

12
您没有点击我提供的链接。waitsubprocess该类的一种方法。
Olivier Verdier,2010年

1
如果进程写入stdout而没有人读取,则等待可能会死锁
ansgri

子进程的速度可能比操作系统慢2倍-bugs.python.org/issue37790
MonsieurBeilto

2

wait()对我来说很好。子过程p1,p2和p3相同地执行。因此,所有过程都在3秒钟后完成。

import subprocess

processes = []

p1 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
p2 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
p3 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)

processes.append(p1)
processes.append(p2)
processes.append(p3)

for p in processes:
    if p.wait() != 0:
        print("There was an error")

print("all processed finished")

子进程可能比os系统慢2倍-bugs.python.org/issue37790
MonsieurBeilto

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.