将bash脚本中的环境变量从Python分配给当前会话



我有许多bash脚本来帮助设置当前会话环境变量。我需要设置env变量,这样我就可以使用子流程模块在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的内容是可信的,唯一的附加漏洞就是带外问题,如shell shock):

# 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' "$varname" "${!varname}"
done >myvars.environ

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

然后你只需要阅读并解析它们:

#!/usr/bin/env python
env = {}
for var_def in open('myvars.environ', 'r').read().split(''):
(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 中设置环境参数

最新更新