为什么subprocess.Popen不等待子进程终止?

为什么subprocess.Popen不等待子进程终止?,第1张

为什么subprocess.Popen不等待子进程终止?

subprocess.Popen
实例化时,运行程序。但是,它不会等待-它会在后台将其触发,就像您
cmd&
在shell中键入一样。因此,在上面的代码中,您实质上已经定义了竞争条件-
如果插入可以及时完成,它将看起来很正常,但是如果没有,则会得到意外的输出。您无需等待第一个
run()
PID完成,您只需返回其
Popen
实例并继续即可。

我不确定这种行为如何与文档相矛盾,因为Popen上有一些非常清晰的方法似乎表明它没有等待,例如:

Popen.wait()  Wait for child process to terminate. Set and return returnpre attribute.

但是,我确实同意可以改进此模块的文档。

为了等待程序完成,我建议使用

subprocess
的便捷方法
subprocess.call
communicate
Popen
对象上使用(对于需要stdout的情况)。您已经在进行第二次通话了。

### START MAIN# copy some rows from a source table to a destination table# note that the destination table is empty when this script is runcmd = 'mysql -u ve --skip-column-names --batch --execute="insert into destination (select * from source limit 100000)" test'subprocess.call(cmd)# check to see how many rows exist in the destination tablecmd = 'mysql -u ve --skip-column-names --batch --execute="select count(*) from destination" test'process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)try: count = (int(process.communicate()[0][:-1]))except: count = 0

此外,在大多数情况下,您不需要在Shell中运行命令。这是其中一种情况,但是您必须像序列一样重写命令。这样一来,您还可以避免传统的外壳注入,而不必担心引用问题,例如:

prog = ["mysql", "-u", "ve", "--execute", 'insert into foo values ("snargle", 2)']subprocess.call(prog)

这甚至可以正常工作,并且不会像您期望的那样注入:

prog = ["printf", "%s", "<", "/etc/passwd"]subprocess.call(prog)

交互式尝试。您避免了注入外壳的可能性,尤其是在接受用户输入的情况下。我怀疑您正在使用与子进程通信的不太出色的字符串方法,因为您遇到使序列正常工作的麻烦:^)



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5648818.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存