我有很多bash脚本来帮助设置我当前的会话环境变量。 我需要设置env变量,所以我可以使用子进程模块在我的python脚本中运行命令。 这是我执行bash脚本的方式:
. ./file1.sh下面是bash脚本的开头:
echo "Setting Environment Variable..." export HORCMINST=99 echo $HORCMINST ...有没有办法从python脚本调用这些bash脚本或在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.shBelow 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?
最满意答案
在现有脚本中使用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脚本,那么这是一个非常合理的事件!
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\0' "$varname" "${!varname}" done >myvars.environReading 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)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 hereNow, 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!
更多推荐
发布评论