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

时间:2017-01-17 22:51:07

标签: python linux bash shell

我有很多bash脚本来帮助设置我当前的会话环境变量。我需要设置env变量,所以我可以使用子进程模块在我的python脚本中运行命令。这就是我执行bash脚本的方式:

. ./file1.sh

以下是bash脚本的开头:

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

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

3 个答案:

答案 0 :(得分:1)

使用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脚本,这是一个非常合理的事件!

答案 1 :(得分:0)

您应该考虑Python内置os module。属性 os.environ是一个环境变量字典,您可以读取,例如

import os
os.environ["USER"]

但是,你不能从子进程 bash环境变量(参见例如How to use export with Python on Linux)。

答案 2 :(得分:0)

之前您的两个问题都已得到解答。 你可以用python执行bash脚本,比如;

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

请参阅此问题running bash commands in python

最好直接在Python中设置环境变量,请参阅此问题How to set environment variables in Python