【问题标题】:Run Process and Don't Wait运行进程,不要等待
【发布时间】:2011-03-31 18:27:24
【问题描述】:

我想运行一个进程,而不是等待它返回。我已经尝试使用 P_NOWAIT 和子进程进行生成,如下所示:

app = "C:\Windows\Notepad.exe"
file = "C:\Path\To\File.txt"

pid = subprocess.Popen(
    [app, file], 
    shell=True, 
    stdin=subprocess.PIPE, 
    stdout=subprocess.PIPE,
).pid

但是,在我关闭记事本之前,控制台窗口仍然存在。是否可以启动该过程而不等待它完成?

【问题讨论】:

  • 你使用的是python.exe还是pythonw.exe
  • 显然 python 足够聪明,可以意识到那些反斜杠不是转义字符,但是,我会通过使用 r'C:\path' 甚至更好的 'C:/path' 来避免这样做
  • @NickT 或者只是单引号而不是双引号
  • @aking1012 单引号和双引号字符串的解析方式不同?不知道
  • @aking1012:你是; Python 不会区别对待单引号和双引号。

标签: python windows subprocess


【解决方案1】:

此调用不会等待子进程终止(在 Linux 上)。不要问我close_fds 是做什么的;几年前我写了代码。 (顺便说一句:subprocess.Popen 的文档令人困惑,恕我直言。)

proc = Popen([cmd_str], shell=True,
             stdin=None, stdout=None, stderr=None, close_fds=True)

编辑:

我查看了subprocess 的文档,我相信对您来说重要的方面是stdin=None, stdout=None, stderr=None,。否则 Popen 会捕获程序的输出,您应该查看它。 close_fds 使子进程无法访问父进程的文件句柄。

【讨论】:

  • 我需要 win32 DETACHED_PROCESS 标志,否则它会挂在 Windows 上。
  • 根据 [1] shell=True 可能存在安全隐患,如果 shell 为 True,建议将 args 作为字符串传递(我在使用序列和 shell= 错误传递 args 时遇到问题是的。虽然我的 args 序列匹配 shlex 输出)。我很确定分离不需要 shell=True(仅在 Linux 上测试)。
  • 由于大多数答案的args是他们的默认值,这可能可以简化为proc = Popen([cmd_str])(记事本可能不需要shell)。
【解决方案2】:

我终于让它工作了。我正在运行“Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)] win32”。以下是我必须编写的代码:

from subprocess import Popen
DETACHED_PROCESS = 0x00000008
cmd = [
    sys.executable,
    'c:\somepath\someprogram.exe',
    parm1,
    parm2,
    parm3,
]
p = Popen(
    cmd, shell=False, stdin=None, stdout=None, stderr=None,
    close_fds=True, creationflags=DETACHED_PROCESS,
)

这会关闭标准输入/输出的所有管道,并且不会在 shell 中执行被调用的程序。将“creationflags”设置为 DETACHED_PROCESS 似乎对我有用。我忘记了在哪里找到的,但使用了一个示例here

【讨论】:

  • 正确的标记方法是使用 shlex
  • creationflags 仅适用于 windows
【解决方案3】:

我认为最简单的实现方法是使用 os.spawn* 系列函数传递 P_NOWAIT 标志。

例如,这将产生一个cp 进程来将一个大文件复制到一个新目录,而无需等待它。

import os
os.spawnlp(os.P_NOWAIT, 'cp', 'cp', '/path/large-file.db', '/path/dest')

【讨论】:

    【解决方案4】:

    您正在捕获程序的输入和输出,因此只要这些文件描述符保持打开状态,您的程序就不会终止。如果要捕获,则需要关闭文件描述符。如果您不想捕获:

    app = "C:\Windows\Notepad.exe"
    file = "C:\Path\To\File.txt"
    
    pid = subprocess.Popen([app, file]).pid
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 1970-01-01
      • 2018-11-19
      • 2016-08-31
      • 1970-01-01
      相关资源
      最近更新 更多