1

问题可能与像命令行模拟器一样使用 python 子进程模块有关

我编写了一些名为 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 期望所有环境变量的“地图”数据结构。我的应用程序需要导出和设置几个变量。用于设置和导出的脚本是通过运行 say '/bin/appload myapp' 生成的(假设 appload 在路径上始终可用)。我目前做的是当我打电话给 p.communicate 我做以下

p.communicate(input = "eval `/bin/appload myapp`;" + command)

所以基本上在运行命令之前,我调用了基础设施设置。

  1. 有没有办法在 Python 中以更好的方式做到这一点。我想以某种方式将 eval /bin/appload 部分推送到 Popen 类的 env 参数中,或者作为 shell 创建过程的一部分。
  2. 我目前的实施有什么问题?(我觉得这很hacky,但我可能错了)
4

1 回答 1

1
  1. 这取决于如何/bin/appload myapp工作。如果它只保证它会输出 bash 语法,那么在 Python 中解析该输出以构造环境对象几乎肯定会比它的价值更麻烦(您可能需要支持参数和变量扩展、子shell、进程替换等, ETC)。另一方面,如果你确定它/bin/appload myapp只会输出“ VARIABLENAME=someword”形式的行,那么在 Python 中解析就很简单了,如果你愿意,你可以将它移动到你的 Python 代码中。

    有很多不同的方向可以满足这些要求;您可以将输出捕获appload myapp到临时文件中并将子进程设置$BASH_ENV为该文件名;这将导致 shell 在以某些人可能认为更清洁的方式运行命令之前获取环境设置。您可以将您的命令(带有eval-ing 前缀)作为第一个参数Popen并传递给 pass shell=True,然后让其自行Popen执行调用(如有必要,显式设置为 bash )。您可以使用 bash 的选项来指定要在命令行上运行的代码,而不是通过标准输入。您可以通过从 Python 调用 eval 的 shell 来采用多层方法bash$SHELL-cappload myapp环境,然后 exec 在它下面的另一个 shell,这样第一个不会出现在 ps 列表中,并且给定的命令create_shell_process将 shell 全部归于它自己(尽管这并不重要)。您可以做很多事情,这取决于您对 shell 的调用方式、它在 ps 列表中的外观、如果appload myapp输出在 eval 时产生错误时是否希望您的命令仍然运行、等等。但对于一个通用的解决方案,我认为你所拥有的一切都很好。

  2. 除了可能仅来自复制和粘贴代码的装饰性问题或次要问题外,我看不到实现的任何实际问题:create_shell_process不使用其cwd参数,on_successandon_failure参数看起来是可选的,但默认值将破坏东西(你不能打电话None)。

于 2013-03-05T18:02:21.423 回答