2013-03-05 47 views
1

问题Python的子模块可以与Use python subprocess module like a command line simulator与预填充环境

我已经写了一些所谓的my_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) 

我的应用程序的shell命令这里有趣的是env参数。 Python期望像所有环境变量的“映射”数据结构。我的应用程序需要导出和设置几个变量。用于设置和导出的脚本是通过运行say'/ bin/appload myapp'(假设appload始终可用于路径)生成的。我现在做的是 当我跑我所说的基础设施建立的命令之前调用p.communicate我下面

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

所以基本上。

  1. 有什么办法可以在Python中以更好的方式做到这一点。我以某种方式想要将eval/bin/appload部件推送到Popen类的OR参数或作为壳创建过程的一部分。
  2. 我目前的实施有哪些问题? (我觉得这是哈克,但我可能是错的)
+0

所述Env映射可以基于'os.environ'映射,见[此旧矿答案](http://stackoverflow.com/questions/10935786/executing-python-subprocess-via- git-hook/10936091#10936091)为例。不知道如何将'/ bin/appload myapp'中的设置捕获到映射中。 – 2013-03-05 10:27:08

+0

我可能会将其作为Jenkins作业运行,并且jenkins用户可能没有设置所有env变量。我可以从/ bin/appload myapp读取输出,并手动在MAP设置中写入相应内容,并按照您的显示使用它,但我将不得不为每个应用程序执行此操作,这是我试图避免的。我公司的所有cmd行应用程序都遵守/ bin/appload命令并打印需要“eval”编辑的内容 – 2013-03-05 10:42:17

回答

1
  1. 这要看/bin/appload myapp作品。如果它只保证它会输出bash语法,那么为了构建环境对象而解析Python中的输出结果几乎肯定会比它的价值更麻烦(您可能需要支持参数和变量扩展,子壳,进程替换等等等)。另一方面,如果您确定/bin/appload myapp只会输出“VARIABLENAME=someword”格式的行,那么在Python中分析这些内容非常简单,如果您愿意,可以将它移动到Python代码中。

    有很多不同的方向可以符合这些要求;您可以将appload myapp的输出捕获到临时文件中,并将子进程的$BASH_ENV设置为该文件名;这可能会导致shell在以某种可能认为更清晰的方式运行命令之前获取环境设置。你可以给你的命令(与eval -ing前缀)作为第一个参数Popen并通过shell=True,让Popenbash调用自身(设置$SHELL明确来砸如有必要)。您可以使用bash的-c选项来指定要在命令行上运行的代码,而不是通过stdin。你可以通过调用一个Python的shell来实现多层的方法,这个shell的环境是appload myapp,然后是exec的另一个shell,所以第一个不会出现在ps列表中,并且create_shell_process给出的命令的shell全部为本身(尽管这应该不重要)。你可以做很多事情,这取决于你关心的是如何调用shell,它在ps列表中看起来如何,你是否希望你的命令仍然运行,如果在eval'd时appload myapp输出产生错误等等。但对于一个通用的解决方案,我认为你拥有的是完美的。

  2. 我没有看到执行任何实际问题,除了化妆品的东西或小的东西,大概只有从复制出来,并粘贴代码:create_shell_process不使用其cwd参数,以及on_successon_failure参数看就像它们是可选的,但默认设置会破坏事情(您不能拨打None)。

+0

其实在2中没有关注我必须采取这些行来产生一个简洁的代码示例。当我修改我的代码以使其“堆栈溢出”时,我也错过了这个CWD事物。 – 2013-03-06 10:24:27