将来自bash脚本的环境variables分配给来自Python的当前会话

我有许多bash脚本来帮助设置我当前的会话环境variables。 我需要envvariables设置,所以我可以使用subprocess模块在我的python脚本中运行命令。 这是我如何执行bash脚本:

. ./file1.sh 

以下是bash脚本的开始:

 echo "Setting Environment Variable..." export HORCMINST=99 echo $HORCMINST ... 

有没有办法从python脚本调用这些bash脚本,或者在python脚本中做类似的事情?

在现有脚本中使用shell=True

首先,就最简单的事情而言 – 如果您使用的是shell=True ,那么您可以告诉shell已经开始运行未经修改的预先存在的脚本的内容。

那就是说 – 如果你最初是这样做的话:

 subprocess.Popen(['your-command', 'arg1', 'arg2']) 

…然后您可以执行以下操作来执行相同的命令,并具有几乎相同的安全保证(只有当file1.sh的内容受信任时,唯一的额外漏洞是带外的问题,例如shellshock ):

 # this has the security of passing explicit out-of-band args # but sources your script before the out-of-process command subprocess.Popen(['. "$1"; shift; exec "$@"', "_", "./file1.sh", "your-command", "arg1", "arg2"], shell=True) 

使用/proc/self/environ在NUL分隔的流中导出环境变量

理想的做法是以明确的形式导出环境变量(一个NUL分隔的流是理想的),然后在Python中解析这个流(这是一个非常明确的格式)。

假设Linux,你可以导出一组完整的环境变量,如下所示:

 # copy all our environment variables, in a NUL-delimited stream, to myvars.environ cat </proc/self/environ >myvars.environ 

…或者您可以手动导出一组特定的变量:

 for varname in HORCMINST PATH; do printf '%s=%s\0' "$varname" "${!varname}" done >myvars.environ 

在Python中读取和解析NUL分隔的流

那么你只需要阅读和解析它们:

 #!/usr/bin/env python env = {} for var_def in open('myvars.environ', 'r').read().split('\0'): (key, value) = var_def.split('=', 1) env[key] = value import subprocess subprocess.Popen(['your-command', 'arg1', 'arg2'], env=env) 

您也可以通过运行os.environ[key]=value立即应用这些变量。


在bash中读取和解析NUL分隔的流

顺便说一句,相同的格式也很容易在bash中解析:

 while IFS= read -r -d '' var_def; do key=${var_def%%=*} value=${var_def#*=} printf -v "$key" '%s' "$value" export "$key" done <myvars.environ # ...put the rest of your bash script here 

现在, 为什么一个NUL分隔的流? 由于环境变量是C字符串 – 与Python字符串不同,它们不能包含NUL。 因此,NUL是唯一可以安全地用来划分它们的字符。

例如,试图使用换行符的人可能会受到包含文字换行符的环境变量的阻碍 – 如果有人将一个短Python脚本嵌入到环境变量中,那么这是一个非常合理的事件!

你应该考虑Python内置的os 模块 。 属性os.environ是你可以读取的环境变量的字典,例如

 import os os.environ["USER"] 

但是,您不能从子进程编写 bash环境变量(请参阅,例如, 如何在Linux上使用Python导出 )。

你的两个问题之前都有答案。 你可以用python来执行bash脚本,

 import subprocess subprocess.Popen("cwm --rdf test.rdf --ntriples > test.nt") 

看到这个问题在Python中运行bash命令

在Python中直接设置环境变量,看看这个问题如何在Python中设置环境变量