Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
602 views
in Technique[技术] by (71.8m points)

linux - Assign environment variables from bash script to current session from Python

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

Below is the beginning of the bash script:

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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'])

...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)

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.

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

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(''):
  (key, value) = var_def.split('=', 1)
  env[key] = value

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

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


Reading and parsing a NUL-delimited stream in 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

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.

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!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...