将bash脚本中的环境变量分配给Python中的当前会话 [英] Assign environment variables from bash script to current session from Python

查看:90
本文介绍了将bash脚本中的环境变量分配给Python中的当前会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have many bash scripts to help set my current session environment variables. I need the env variables set so I can use the subprocess module to run commands in my python scripts. This is how I execute the bash scripts:

. ./file1.sh

以下是bash脚本的开头:

Below is the beginning of the bash script:

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

是否可以从python脚本调用这些bash脚本,或者在python脚本中执行类似的操作?

Is there a way to call these bash scripts from a python script or do something similar within a python script?

推荐答案

在现有脚本中使用shell=True

首先,就最简单的事情而言-如果您使用的是shell=True,则可以告诉外壳程序在不修改的情况下开始运行您先前存在的脚本的内容.

Using shell=True With Your Existing Script

First, in terms of the very simplest thing -- if you're using shell=True, you can tell the shell that starts to run the contents of your preexisting script unmodified.

也就是说-如果您最初是这样做的:

That is to say -- if you were initially doing this:

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

...然后,您可以执行以下操作以几乎相同的安全性保证执行同一命令(只要可信的file1.sh内容,唯一的其他漏洞就是带外问题)例如shellshock):

...then you can do the following to execute that same command, with almost the same security guarantees (the only additional vulnerabilities, so long as the contents of file1.sh are trusted, are to out-of-band issues such as 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中解析该流(格式非常明确).


Using /proc/self/environ to export environment variables in a NUL-delimited stream

The ideal thing to do is to export your environment variables in an unambiguous form -- a NUL-delimited stream is ideal -- and then parse that stream (which is in a very unambiguous format) in Python.

假设使用Linux,则可以按如下所示导出完整的环境变量集:

Assuming Linux, you can export the complete set of environment variables as follows:

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

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

...or you can export a specific set of variables by hand:

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


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

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


Reading and parsing a NUL-delimited stream in Python

Then you just need to read and parse them:

#!/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立即应用这些变量.

You could also immediately apply those variables by running os.environ[key]=value.

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

Incidentally, that same format is also easy to parse in 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是可以安全地用于分隔它们的唯一且唯一的字符.


Now, why a NUL-delimited stream? Because environment variables are C strings -- unlike Python strings, they can't contain NUL. As such, NUL is the one and only character that can be safely used to delimit them.

例如,尝试使用换行符的某人可能会受到包含文字换行符的环境变量的困扰-如果有人将一个简短的Python脚本嵌入到环境变量中,这是一个非常合理的事件!

For instance, someone who tried to use newlines could be stymied by an environment variable that contained a literal newline -- and if someone is, say, embedding a short Python script inside an environment variable, that's a very plausible event!

这篇关于将bash脚本中的环境变量分配给Python中的当前会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆