【问题标题】:Starting module shell command from python subprocess module从 python 子进程模块启动模块 shell 命令
【发布时间】:2011-10-30 16:37:11
【问题描述】:

我正在尝试运行 vnc 服务器,但首先我需要运行“模块加载 vnc”。

如果我在加载的 bash shell 中调用 which module,那么 not found 中的命令是 PATH 但同时它是可用的。看起来命令是内置的。

换句话说,我似乎需要一次执行两个命令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 shell,但它以字符串而不是进程开头,即我在 ps 中看到我想启动的命令完全相同。

您能否建议如何从子进程模块启动此命令?是否可以以shell=False 开头?

【问题讨论】:

  • module load vnc 是否需要在与vncserver 相同的shell/命令中运行?为什么需要/bin/bash/bin/sh 几乎可以肯定是/bin/bash 的符号链接。
  • 你需要一个shell来执行多个命令。您可以尝试'bash -c "module load vnc; vncserver :8080 -localhost"' 之类的方法,但这可能不是真正正确的方法。
  • @tripleee 这就是他所说的shellexecutable 参数的作用
  • @agf 是的,但如果他需要相同的 bash,他可以使用 shell=false 并使用 bash -c '...' 作为运行的单个命令。
  • @agf,是的,它应该在同一个 shell 中运行。你是对的,/bin/sh 是 bash 的符号链接。我认为那不应该有区别。

标签: python bash subprocess environment-modules


【解决方案1】:

如果您想使用 shell=False 进行此操作,只需将其拆分为两个 Popen 调用即可。

subprocess.check_call('module load vnc'.split())
subprocess.Popen('vncserver :8080 -localhost'.split())

【讨论】:

  • module 可能是 Environment Modules shell 内置的,而不是可执行文件。
【解决方案2】:

环境模块通常只为您修改几个环境变量。通常可以完全跳过module load whatever 步骤,而不依赖于这些模块。我推荐

subprocess.Popen(['/possibly/path/to/vncserver', ':8080', '-localhost'], 
                 env={'WHATEVER': 'you', 'MAY': 'need'})

而不是加载模块。

如果你坚持使用这个基本方法,那么你想用Popen(['bash',...自己开始bash。

【讨论】:

  • 谢谢你,迈克。我也在考虑直接启动vncserver,但是我找不到vncserver文件在哪里,并且不知道指定vnc模块后如何扩展环境。
  • @yart,在这种情况下 Popen(["bash", "-c", "module load vnc; vncserver :8080 -localhost"]) 或任何可能是您最好的选择。
  • 迈克,谢谢。此命令返回 127 退出代码,但如果我指定“-ci”而不是“-c”,它会起作用。为什么它只适用于交互式 shell?
  • @yart,定义 module 内置函数的代码可能在 bashrc 而不是 bash_profile/profile,因此 module 从未在非交互式中定义会议。就个人而言,我通常让我的个人~/.bash_profile 执行我的~/.bashrc
【解决方案3】:

您可以从 Python 脚本调用 modulemodule 命令由 environment-modules 软件提供,该软件还提供了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'])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 2016-10-12
    相关资源
    最近更新 更多