python subprocess.Popen(shell = True)创建的进程的pid不是生成的shell的pid

时间:2014-12-11 13:02:16

标签: python linux shell subprocess

我有一个用于测试的python脚本:

test.py:
#coding=utf-8
import os
import time

print os.getpid()

通过subprocess.Popen:

调用它
p = sp.Popen("python test.py", shell=True)
print p.pid

这两个print语句的不同输出是预期的,因为p.pid应该是生成的shell进程的pid,但实际输出是:

In [18]: p = sp.Popen("python test.py", shell=True)

In [19]: 19108

In [19]: p.pid
Out[19]: 19108

1 个答案:

答案 0 :(得分:2)

我相信你在UNIX / Linux上。如果我可以重述你的问题,我认为你问的是,给定

p = subprocess.Popen("python test.py", shell=True)

为什么p.pidtest.py进程相同,而不是介入的 shell ,您明确请求的shell?也就是说,您希望流程族谱看起来像这样:

python (calling subprocess.Popen)   # pid 123
  \_ /bin/sh -c 'python test.py'    # pid 124
      \_ python test.py             # pid 125  # note: pids need not be sequential, that's just for demonstration

答案是,你的shell正在进行优化。 shell认识到它已经被赋予了一个简单的命令,只需要execve该命令,替换它自己 - 但不是它的PID当然 - 有了新的流程。因此,家谱看起来像这样:

python (calling Popen)                          # pid 201
  \_ /bin/sh -c ... --execve--> python test.py  # pid 202

在Linux上,您可以strace -fe trace=process ...进行确认。您将看到顶级python进程分支(呃,clone),然后子进程/bin/sh再执行python