从Python子进程模块启动模块Shell命令
我正在尝试运行VNC服务器,但在此之前我需要先执行一个命令:'module load vnc'。
如果我在已经加载的bash终端中输入 which module
,系统会提示找不到这个命令,虽然它实际上是可以用的。这看起来像是一个内置命令。
换句话说,我似乎需要同时执行两个命令 module load vnc;vncserver :8080 -localhost
,而我正在写一个脚本来从Python启动它。
我尝试了不同的方式使用 subprocess.Popen
,比如:
subprocess.Popen('module load vnc;vncserver :8080 -localhost', shell=True)
结果返回了 127
的退出代码,或者提示 command not found
。
subprocess.Popen('module load vnc;vncserver :8080 -localhost', shell=False)
显示了
File <path>/subprocess.py line 621, in \__init__
errread, errwrite)
OSError: [Errno 2] No such file or directory.
如果我指定 shell=True
,它会从 /bin/sh
执行,但我需要的是从 /bin/bash
执行。
指定 executable='/bin/bash'
并没有帮助,因为它加载了一个新的bash终端,但它是以字符串的形式启动,而不是作为一个进程,也就是说,我在 ps
列表中看到的命令和我想要启动的命令是完全一样的。
请问你能给我一些建议,如何通过subprocess模块启动这个命令吗?是否可以在 shell=False
的情况下启动它?
3 个回答
你可以在Python脚本中使用module
这个命令。这个module
命令是由一种叫做环境模块的软件提供的,它还提供了一个叫python.py
的初始化脚本。
在Python脚本中运行这个初始化脚本,就可以启用module
这个Python功能。如果环境模块安装在/usr/share/Modules
这个路径下,你可以在/usr/share/Modules/init/python.py
找到这个脚本。
下面的代码可以启用module
的Python功能:
import os
exec(open('/usr/share/Modules/init/python.py').read())
之后,你就可以加载你的模块并启动你的应用程序了:
module('load', 'vnc')
subprocess.Popen(['vncserver', ':8080', '-localhost'])
如果你想在不使用 shell=False
的情况下实现这个功能,可以把它分成两个 Popen
调用。
subprocess.check_call('module load vnc'.split())
subprocess.Popen('vncserver :8080 -localhost'.split())
环境模块通常只是为你修改几个环境变量。其实你可以完全跳过 module load whatever
这一步,直接不依赖这些模块。我建议
subprocess.Popen(['/possibly/path/to/vncserver', ':8080', '-localhost'],
env={'WHATEVER': 'you', 'MAY': 'need'})
根本就不要加载这个模块。
如果你还是想用这种基本的方法,那你可以自己启动 bash,使用 Popen(['bash',...
。