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

时间:2010-08-12 14:45:08

标签: python subprocess

我在Python中编写了一个小的gui-frontend,让用户可以播放互联网广播频道。该程序使用Pythons subprocess()来启动mplayer以调入一个频道,例如:

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

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

3 个答案:

答案 0 :(得分:6)

试试这个:

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将其自身替换为正在运行的命令,从而导致一个进程。

在我看来,用subprocess.Popen调用shell=True是一个非常非常糟糕的主意。通过执行此操作,您将面临大量安全问题,并且通常不太可预测的行为,因为shell元字符由sh -c解释。

答案 1 :(得分:1)

我没有确切的答案,但有几种方法可以调查:

使用pstree检查进程之间的父/子关系。

使用ps -awux查看所有进程的完整命令行参数。

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

两个系统都使用相同版本的mplayer吗?蟒蛇?

答案 2 :(得分:0)

subprocess.Popen返回带有several useful methods的Popen对象。直接使用os.kill来终止事情可能是个坏主意......

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