简体   繁体   English

运行多个Shell命令并等待结果的Python脚本

[英]Python script which runs multiple shell commands and waits for the result

I'm trying to write a python wrapper for building some software. 我正在尝试编写用于构建某些软件的python包装器。 I need to automate building it hundreds of times with different configurations which means I can't just autogen.sh ; ./configure ; make ; make install 我需要使用不同的配置来自动构建数百次,这意味着我不能只使用autogen.sh ; ./configure ; make ; make install autogen.sh ; ./configure ; make ; make install autogen.sh ; ./configure ; make ; make install . autogen.sh ; ./configure ; make ; make install Some of the configurations I use require running a script which conditionally set up some environment variables. 我使用的某些配置需要运行一个脚本,该脚本有条件地设置了一些环境变量。 What I want is to be able to do something like this: 我想要做的是这样的事情:

command = './autogen.sh'
ret = subprocess.call(command.split())
if ret != 0:
  sys.exit(ret)

command = './script.sh ; ./configure <configure-flags>'
ret = subprocess.call(command.split())
if ret != 0:
  sys.exit(ret)

command = 'make'
ret = subprocess.call(command.split())
if ret != 0:
  sys.exit(ret)

command = 'make install'
ret = subprocess.call(command.split())
if ret != 0):
  sys.exit(ret)

The problem I'm running into is that the environment variables set in script.sh are not getting preserved for configure . 我遇到的问题是script.sh中设置的环境变量没有保留为configure I saw a partial solution in Sending multiple commands to a bash shell which must share an environment , but that involves flushing the commands to stdin and polling for a result which won't really work when you have a really long makefile (mine takes about 10 - 20 minutes) and it also doesn't give you the return value which I need to know if the build was successful or not. 在将多个命令发送到必须共享一个环境的bash shell中,我看到了部分解决方案,但这涉及到将命令刷新到stdin并进行轮询,以获取结果,当您的makefile太长时,该结果将不起作用(我的文件大约需要10个-20分钟),它也不会给您返回值,我需要知道该返回值是否可以成功建立。

Does anyone know a better way to do this? 有人知道更好的方法吗?

If you have a script that sets variables you want to access afterwards, you must source it (similar to what other languages call "include"). 如果您具有一个脚本,该脚本设置了以后要访问的变量,则必须将其来源(类似于其他语言称为“ include”的内容)。

Instead of 代替

command = './script.sh ; ./configure <configure-flags>'
ret = subprocess.call(command.split())

you can do 你可以做

command = ["bash", "-c", "source script.sh; ./configure"]
subprocess.call(command)

The basic problem here is that environment variables are copied only "downward" (from parent to child), never "upward" (child to parent). 这里的基本问题是环境变量仅“向下”复制(从父级复制到子级),而不是“向上”复制(子级到父级)。 Your python script is a parent. 您的python脚本是父级。 It runs a shell command, which is therefore a child; 它运行一个shell命令,因此它是一个子命令; the shell runs more commands, which are children of the shell (and therefore grandchildren of the Python process). Shell运行更多命令,这些命令是Shell的子级(因此是Python进程的子级)。

To make environment variables persist, you'll need to import them upwards somehow. 为了使环境变量持久存在,您需要以某种方式向上导入它们。 Exactly how is up to you. 完全取决于您。 A common technique (used in shell scripts as well as in Python) is to have the exporter print the values it wants set, then have the shell or Python process read that output and do the setting. 一种常用的技术(在Shell脚本和Python中都使用过)是让导出器打印它想要设置的值,然后让Shell或Python进程读取该输出并进行设置。 (I see that's what the post you linked-to does.) (我看到的就是您链接到的帖子。)

For instance, a child process might print: 例如,子进程可能会打印:

CONFIG_PATH=/path/to/config/file

(or the same with export added) and then the outer shell would simply eval this. (或与export相同),然后外壳将对此进行简单eval This implies a great deal of trust: what if the child process print rm -rf / for instance? 这意味着非常信任:例如,如果子进程打印rm -rf /怎么办? One can apply rules (regular expression matching, for instance) to the output before executing it, or even manually (or automatically) parse it but not execute the result until after a verification step. 可以在执行输出之前将规则(例如,正则表达式匹配)应用于输出,甚至可以手动(或自动)解析它,但是直到验证步骤之后才执行结果。

Another method is to write the configuration to a file, and have the parent read the file. 另一种方法是将配置写入文件,然后让父级读取该文件。 This is pretty much the same technique, but using a file for the communications depot, instead of fiddling with stdin and stdout. 这几乎是相同的技术,只是使用文件作为通信仓库,而不是摆弄stdin和stdout。 It has several more issues (naming the file, and knowing when to read it). 它还有其他几个问题(命名文件以及知道何时读取文件)。

(There are, of course, many build and/or test frameworks written in Python. I'm not going to recommend any specific ones as I don't have that much experience with them.) (当然,有很多用Python编写的构建和/或测​​试框架。由于我对它们没有太多的经验,因此我不推荐任何特定的框架。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM