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

fri*_*igg 4 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)
Run Code Online (Sandbox Code Playgroud)

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

os.kill(p.pid, 9)
Run Code Online (Sandbox Code Playgroud)

这在OpenSUSE中完美运行,但在Ubuntu中不行.似乎Ubuntu实际上启动了两个独立的进程.终端输出:

Opensuse 11.3:

$ pgrep mplayer
22845
Run Code Online (Sandbox Code Playgroud)

Ubuntu 10.04:

$ pgrep mplayer
22846
22847
Run Code Online (Sandbox Code Playgroud)

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

Omn*_*ous 6

试试这个:

p = subprocess.Popen(runn.split(), shell=False)
Run Code Online (Sandbox Code Playgroud)

我猜这是怎么回事......

当你说shell=Truesubprocess实际启动这个命令sh -c "your string".sh然后该命令解释您的字符串并运行该命令,就像您在shell提示符下输入的那样(或多或少).通常这会导致两个过程.一个是sh -c "your string",而另一个是它的孩子,your string.

某些版本sh具有优化,exec在某些条件下它们将自动执行命令.他们这样做,如果它是最后一个命令sh将要运行,sh没有其他理由坚持下去.当sh -c用于运行命令时,这几乎总会导致调用sh将其自身替换为正在运行的命令,从而导致一个进程.

在我看来,这是一个非常,非常糟糕的主意永远调用subprocess.Popenshell=True.通过这样做,你正在为自己打开大量安全问题,并且通常不太可预测的行为,因为shell元字符被解释sh -c.