python脚本中的Bash源代码

时间:2015-05-27 07:34:42

标签: python bash

我正在编写一个包装python脚本,在运行其他工具之前需要source ./config。排除我的脚本提供的额外功能,它基本上是这样做的:

$ source ./config
$ ./a-tool.sh --args
$ ./another-tool.py --arg1 --arg2

转换为python,我可以做一些事情来调用这两个脚本:

subprocess.call(['./a-tool.sh', '--args'])
subprocess.call(['./another-tool.py', '--arg1', '--arg2'])

但我无法首先弄清楚如何source,使用修改后的工具环境。我已阅读Emulating Bash 'source' in Python,但它建议修改运行脚本的环境,这不是我想要的。

编辑:

为了澄清,我的脚本目前是一个bash脚本,它执行一系列检查,解析一些参数,并根据结果运行一个或多个工具,如上所述。 source行并不总是需要,并不总是相同。但是,在使用它时,所有以下工具都需要在相同的环境中运行(即bash过程)。在bash中,这很容易。但是,我想在python中重写脚本,因为其他一些功能对我来说更容易在python中编写和维护。它纯粹是一种基于偏好的语言选择,与实际功能无关。根据@abarnert的回答,我想我可以做类似

的事情
subprocess.call(['source', '.config', ';', './a-tool.sh', ...])

虽然看起来不容易调试,所以我更喜欢这样的东西:

bash = subprocess.run('bash')
bash.execute('source ./config')
bash.execute('a-tool.sh --args')

在python中有什么办法吗?

3 个答案:

答案 0 :(得分:2)

所有source都会在当前bash解释器的上下文中运行脚本。

Python解释器不是bash解释器,所以你所要求的没有任何意义。 *

通常,所有source用于影响环境变量,因此those "hacks" you linked正在做什么。这不是真正的黑客攻击。它假设脚本除了设置环境变量之外没有任何影响 - 但这应该是一个很好的假设;如果没有,那么无论它做什么,都只是你无法用Python做的事情。

或者,您可以创建一个bash子进程,并将其用于source脚本,然后运行其他程序,而不是直接将每个程序作为Python的子进程运行。 (无论是动态构建脚本,还是以非tty stdin为其提供脚本。)这是执行源脚本可能执行的所有操作的唯一真正安全的方法(因为这是实际获取脚本的唯一方法)。 / p>

或者,作为稍微不同的hack,将每个命令连接到您想要source的脚本的末尾,并将其作为单独的bash子进程运行。只要没有孩子试图改变父母环境中的东西等,通常会工作。

* 可能bash作为父母......但它可能很容易......而且,即使它确实如此,仍然不会做你想要的除非您尝试做的唯一事情是影响环境变量。

答案 1 :(得分:0)

我认为你不能这样做。因为在bash中使用source somefile时,somefile将在SAME进程中作为主脚本执行。因此,如果在export中放置一些somefile语句,则主脚本中将提供环境变量。

但是,在您的情况下,python将创建一个新进程(作为与当前python脚本对应的进程的子进程)并执行source操作。在那之后,该过程将结束并被销毁。是的,source操作已成功完成,但在子进程中。父进程中的环境变量在子进程中可用,但反之亦然。

您应该按照问题中的链接进行操作。在该过程中,环境变量在当前进程中创建,即运行python脚本的进程。

答案 2 :(得分:0)

我同意评论中的@Leon:切换谁执行什么的角色。

#!/bin/bash
source /my/conf.sh
python /my/script-1.py
python /my/script-2.py

sourced bash配置可以导出ENV变量,然后从python你可以用os.environ []读取它们。

这是AFAIK,接受的方法,用于解决这些问题。