Python popen 命令。等到命令完成

Python popen command. Wait until the command is finished

提问人:michele 提问时间:5/15/2010 最后编辑:DennisLimichele 更新时间:11/4/2020 访问量:240642

问:

我有一个脚本,我在其中使用 popen a shell 命令启动。 问题在于脚本不会等到 popen 命令完成并立即继续。

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

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

python 子进程 等待 popen

评论


答:

7赞 Olivier Verdier 5/15/2010 #1

你要找的是等待方法。

评论

0赞 michele 5/15/2010
但是如果我输入: om_points = os.popen(data[“om_points”]+“ > ”+diz['d']+“/points.xml”, “w”).wait() 我收到此错误: 回溯(最近一次调用最后一次): 文件 “./model_job.py”,第 77 行,在 <模块中> om_points = os.popen(data[“om_points”]+“ > ”+diz['d']+“/points.xml”, “w”).wait() AttributeError:“file”对象没有属性“wait” 问题是什么?再次感谢。
14赞 Olivier Verdier 5/17/2010
您没有点击我提供的链接。 是类的方法。waitsubprocess
3赞 ansgri 12/19/2016
如果进程写入 stdout 并且没有人读取它,则等待可能会死锁
0赞 MonsieurBeilto 3/8/2020
子进程的速度可能比操作系统慢 2 倍 - bugs.python.org/issue37790
1赞 eDonkey 7/22/2022
@MonsieurBeilto 已被弃用;它已被替换为os.systemsubprocess
138赞 unholysampler 5/15/2010 #2

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

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

如果要在执行时执行操作或将操作馈入,则可以在调用后使用。stdincommunicatepopen

#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

评论

1赞 thornomad 5/15/2010
查看 subprocess.call 上的文档
0赞 Chang 7/20/2019
虽然子进程在许多答案中是首选,但它不能很好地处理命令中的空间和配额。上面的回答并没有直接解决os.popen问题。
0赞 MonsieurBeilto 3/8/2020
子进程的速度可能比操作系统慢 2 倍 - bugs.python.org/issue37790
2赞 LoMaPh 9/23/2020
subprocess.run()在 Python 3.5 中添加,是“调用子进程的推荐方法”
45赞 Touchstone 8/15/2016 #3

你可以用它来实现这一点。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

评论

0赞 MonsieurBeilto 3/8/2020
子进程的速度可能比操作系统慢 2 倍 - bugs.python.org/issue37790
13赞 Chidhambararajan NRM 4/13/2018 #4

让尝试传递的命令成为

os.system('x')

然后你把它隐藏成一个声明

t = os.system('x')

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

7赞 simibac 11/16/2018 #5

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")

评论

0赞 MonsieurBeilto 3/8/2020
子进程的速度可能比操作系统慢 2 倍 - bugs.python.org/issue37790
24赞 Alberto 11/21/2019 #6

强制在读取所有输出之前不继续:popen

os.popen(command).read()

评论

3赞 jdmcnair 2/21/2020
我不是 python 专家,但这似乎是对原始代码进行最少修改的最简单解决方案。有什么原因不是一个好的解决方案?
0赞 Marc Maxmeister 9/4/2021
@jdmcnair我的猜测是,如果命令抛出错误,这个 .read() 方法会破坏父进程。但是,其他一些方法可以将子进程中的错误与影响父进程的错误分离。我猜如果子进程永远挂起,.read()将永远等待结果。
0赞 Barsha Lamichhane 11/4/2020 #7

我认为process.communicate()适用于小尺寸的输出。对于更大的输出,这不是最好的方法。