Python:为什么subprocess()在Ubuntu中启动2个进程,在OpenSUSE中启动1个进程?

问题描述:

我已经在Python中编写了一个小型gui-frontend,它允许用户播放互联网广播频道。该程序使用Python的子过程(),以便initizalize mplayer的调成信道,例如:Python:为什么subprocess()在Ubuntu中启动2个进程,在OpenSUSE中启动1个进程?

runn = "mplayer http://77.111.88.131:8010" 
p = subprocess.Popen(runn, shell=True) 
pid = int(p.pid) 
wait = os.waitpid(p.pid, 1)

然后保存p.pid,并且当用户想要停止监听以下代码用于:

os.kill(p.pid, 9)

这在OpenSUSE中完美运行,但在Ubuntu中无法运行。看来,Ubuntu实际上启动了两个独立的进程。端子输出:

的openSUSE 11.3:

$ pgrep mplayer 
22845 

的Ubuntu 10.04:

$ pgrep mplayer 
22846 
22847 

运行的其他程序时,这也适用。有谁知道为什么?我真的希望这个应用程序运行在所有发行版上,所以任何帮助深表谢意。

+0

'ps -ef |的输出是什么? fgrep mplayer'? – Omnifarious 2010-08-12 14:51:46

试试这个:

p = subprocess.Popen(runn.split(), shell=False) 

我为发生的事情的猜测是,这个...

当你说shell=True子真正开始这个命令sh -c "your string"sh命令然后解释你的字符串并运行命令,就好像你在shell提示符下键入的那样(或多或少)。通常这会导致两个过程。一个是sh -c "your string",另一个是孩子,your string

某些版本的sh进行了优化,在某些情况下它们会自动exec命令。他们这样做,如果这是最后的命令sh即将运行,并且sh没有其他原因坚持。使用sh -c运行命令时,几乎总是会导致调用sh将其自身替换为正在运行的命令,从而导致一个进程。

在我看来,这是一个非常非常糟糕的想法,曾用shell=True调用subprocess.Popen。这样做会让你自己面对大量的安全问题,并且由于shell元字符被解释为sh -c而通常不太可预测的行为。

+0

非常感谢您的详细解释!这解决了我的问题。祝你有个美好的一天:) – frigg 2010-08-13 06:27:59

我没有一个确切的答案,但这里有几个方面进行调查:

使用pstree检查过程之间的父/子关系。使用ps -awux查看所有进程的完整命令行参数。

请注意,使用shell=True会启动一个启动mplayer的shell进程(例如/bin/bash)。这可能是另一个调查途径。这两个系统是否使用相同的shell?

这两个系统是否使用相同版本的mplayer?蟒蛇?

subprocess.Popenseveral useful methods返回一个Popen对象。这可能是一个坏主意,通过直接使用os.kill终止事情...

如果您使用Popen对象的p.terminate()p.kill()方法是否会发生同样的事情?

+0

刚刚意识到p.terminate()在Python 2.6之前并不存在,我猜这就是为什么OP使用'os.kill(p.pid)'......猜猜我应该阅读docs我正在指向其他人! – 2010-08-12 15:03:54