问题可能与Use python subprocess module like a command line simulator
有关我已经写了一些名为my_shell的基础设施代码,你可以传递我的应用程序的shell命令,看起来像这样
class ApplicationTestShell(object):
def __init__(self):
'''
Constructor
'''
self.play_ground_dir = "/var/tmp/MyAppDir"
ensure_dir_exists_and_empty(self.play_ground_dir)
def execute_command(self, command, on_success = None, on_failure = None):
p = create_shell_process(self, self.play_ground_dir)
sout, serr = p.communicate(input = command)
if p.returncode == 0:
on_success(sout)
else:
on_failure(serr)
def create_shell_process(self, cwd):
return Popen("/bin/bash", env= {WHAT DO I DO HERE?},cwd = test_dir, stdout=PIPE, stderr=PIPE, stdin=PIPE)
这里有趣的是env参数。 Python期望像所有环境变量的“map”数据结构。我的应用程序需要导出和设置多个变量。设置和导出的脚本是通过运行说'/ bin / appload myapp'生成的(假设appload始终在路径上可用)。我现在做什么 当我打电话给p.communicate时,我会做以下
p.communicate(input = "eval `/bin/appload myapp`;" + command)
所以基本上在运行命令之前我称之为基础架构设置。
答案 0 :(得分:1)
这取决于/bin/appload myapp
的工作原理。如果它只保证它将输出bash语法,那么在Python中解析该输出以构造环境对象几乎肯定会有更多麻烦(你可能需要支持参数和变量扩展,子shell,进程替换等)等)。另一方面,如果您确定/bin/appload myapp
只会输出“VARIABLENAME=someword
”形式的行,那么在Python中解析这一点非常简单,如果您将它移动到Python代码中等。
你可以根据这些要求提出许多不同的指示;您可以将appload myapp
的输出捕获到临时文件中,并将子进程的$BASH_ENV
设置为该文件名;这会导致shell在以某些人认为更干净的方式运行命令之前获取环境设置。您可以将命令(使用eval
- 前缀)作为Popen
的第一个参数并传递shell=True
,然后让Popen
执行bash
调用单独(如有必要,明确设置$SHELL
bash)。您可以使用bash的-c
选项指定要在命令行上运行的代码,而不是通过stdin。您可以通过从Python调用一个shell来进行多层方法,其中eval是appload myapp
环境,然后是exec的另一个shell,因此第一个没有出现在ps列表中,并且命令给了{{ 1}}有自己的shell(虽然这应该不重要)。您可以做很多事情,具体取决于您对shell调用方式的关注点,它在ps列表中的外观,是否希望在create_shell_process
输出产生错误时仍然运行命令当评估时,等等。但是对于一般解决方案,我认为你所拥有的是完全没问题的。
除了复制和粘贴代码之外的整容或小事之外,我没有看到任何实际的实施问题:appload myapp
不使用其create_shell_process
参数,cwd
和on_success
参数看起来像是可选的,但默认值会破坏(您无法调用on_failure
)。