在Python中创建子进程

0 投票
2 回答
584 浏览
提问于 2025-04-17 06:29

我正在尝试使用 subprocess 模块和 Popen 类来创建和运行一个进程。到目前为止,我一直能成功调用我想要的任何程序。

现在我想用一个附带的 Python 脚本来调用 paraview(版本 3.8.1),像这样:

paraview --script=script.py

如果我从控制台运行这个命令,它工作得很好。但是如果我尝试用我的 Popen 类来运行它,就会出现错误信息:

/home/woltan/local/lib/python2.7/site.py:157: Warning: 'with' will become a reserved keyword in Python 2.6
'import site' failed; use -v for traceback
/home/woltan/local/lib/python2.7/linecache.py:127: Warning: 'with' will become a reserved keyword in Python 2.6
/home/woltan/local/lib/python2.7/site.py:157: Warning: 'with' will become a reserved keyword in Python 2.6
'import site' failed; use -v for traceback
ERROR: In /home/kitware/Kitware/ParaView-3.8.1/source/Utilities/VTKPythonWrapping/Executable/vtkPVPythonInteractiveInterpretor.cxx, line 75
vtkPVPythonInteractiveInterpretor (0x124e9d0): Failed to locate the InteractiveConsole object.

Paraview 本身是可以启动的。但这个错误信息是因为 paraview 自己有一个 Python 解释器在使用吗?还是说我可以调整我的 Popen 调用方式,它看起来是这样的:

p = subprocess.Popen("paraview --script=script.py", bufsize = -1, shell = True)

为什么从控制台可以创建一个进程,但用上面的 Popen 调用却不行呢?

编辑

我下载并安装了一个运行 Python 2.7 的 paraview 版本(而不是我之前用的 Python 2.5),这时 Popen 的调用就可以正常工作了。所以这肯定和 paraview 的 Python 版本有关。剩下唯一的问题是:为什么用 Popen 启动一个进程会有这么大的区别呢?

2 个回答

1

你看到的错误信息似乎和 subprocess.Popen 没什么关系。我觉得你需要做的是要么加上 shell=True

p = subprocess.Popen("paraview --script=script.py", shell = True)

要么把 args 分开成一个序列:

p = subprocess.Popen(['paraview', '--script=script.py'])

我从来没用过 bufsize,但我觉得在这里它应该没什么影响。

3

这里有两件奇怪的事情:

  1. 通常情况下,这个调用根本不应该成功。因为你设置了 shell=False,所以第一个参数应该用一个序列来传递:

    p = subprocess.Popen(("paraview", "--script=script.py"), bufsize=-1)
    

    (shell=False 是默认设置。)

  2. 你似乎在混用几种不同的Python版本:

    /home/woltan/local/lib/python2.7/site.py:157: Warning: 'with' will become a reserved keyword in Python 2.6
    

提到的 site.py 使用了 with 这个关键词。这是可以的,因为它是为Python 2.7设计的。而你正在使用的Python版本似乎是从Python 2.5来的。在2.4版本时还没有 with,而在2.6版本时已经有了。

撰写回答