【问题标题】:Opening a process with Popen and getting the PID使用 Popen 打开进程并获取 PID
【发布时间】:2011-12-20 20:30:10
【问题描述】:

我正在开发一个漂亮的小功能:

def startProcess(name, path):
    """
    Starts a process in the background and writes a PID file

    returns integer: pid
    """

    # Check if the process is already running
    status, pid = processStatus(name)

    if status == RUNNING:
        raise AlreadyStartedError(pid)

    # Start process
    process = subprocess.Popen(path + ' > /dev/null 2> /dev/null &', shell=True)

    # Write PID file
    pidfilename = os.path.join(PIDPATH, name + '.pid')
    pidfile = open(pidfilename, 'w')
    pidfile.write(str(process.pid))
    pidfile.close()

    return process.pid

问题是process.pid 不是正确的PID。它似乎总是比正确的PID低1。例如,它说进程从 31729 开始,但ps 说它在 31730 运行。每次我尝试它都会关闭 1。我猜它返回的 PID 是 current 进程,而不是启动的进程,并且新进程获得高 1 的“下一个”pid。如果是这种情况,我不能仅仅依靠返回process.pid + 1,因为我不能保证它总是正确的。

process.pid为什么不返回新进程的PID,如何实现我所追求的行为?

【问题讨论】:

  • 尝试删除 shell=True 和你的 > 东西。
  • 我有同样的问题,我发现了一个艰难的方法,它并不总是 PID+1,一开始是,但现在它给了我 +2
  • @Hubro 我想在我自己的一些代码中使用这个漂亮的函数!您介意为processStatus() 发布您的代码吗?
  • @Jordan 太久了,抱歉。我什至不知道我写这个是为了什么。

标签: python subprocess popen


【解决方案1】:

来自http://docs.python.org/library/subprocess.html的文档:

Popen.pid 子进程的进程ID。

注意,如果你将shell参数设置为True,这就是进程 生成的 shell 的 ID。

如果shell 为假,我认为它的行为应该如您所愿。

如果您依赖shellTrue 来使用PATH 环境变量解析可执行路径,您可以使用shutil.which 来完成同样的事情,然后将绝对路径传递给Popen。 (顺便说一句,如果您使用的是 Python 3.5 或更高版本,则应该使用 subprocess.run 而不是 Popen。

【讨论】:

  • 我需要 shell=True 才能使 python 的相对路径正常工作。我想我会用绝对路径替换它并将shell 设置为false。感谢您的信息!
  • 首先通过 os.path.abspath 传递路径应该可以为您解决这个问题。 docs.python.org/library/os.path.html
  • 不,运行os.path.abspath('python') 只会返回我的工作目录加上“python”,例如'/root/python'
  • 啊,我明白了,您依赖于 shell 的 PATH 变量。您可以使用的另一个技巧是执行/usr/bin/env python。我已经看到它主要用于 shell 脚本,但在这里可能会对您有所帮助。
  • 所以我猜你真的想在 Python 中做 $PATH 解析。 stackoverflow.com/questions/377017/… 有一个应该适用的答案。
猜你喜欢
  • 2012-03-16
  • 2011-05-20
  • 1970-01-01
  • 2011-06-11
  • 2021-08-08
  • 2013-04-05
  • 2015-05-02
  • 2022-01-26
  • 1970-01-01
相关资源
最近更新 更多