设置python中调用bash脚本的环境变量

设置python中调用bash脚本的环境变量,python,bash,environment-variables,Python,Bash,Environment Variables,我有一个bash脚本,如下所示: python myPythonScript.py python myOtherScript.py $VarFromFirstScript print("Running some code...") VarFromFirstScript = someFunc() print("Now I do other stuff") 而myPythonScript.py看起来是这样的: python myPythonScript.py python myOtherSc

我有一个bash脚本,如下所示:

python myPythonScript.py

python myOtherScript.py $VarFromFirstScript
print("Running some code...")
VarFromFirstScript = someFunc()
print("Now I do other stuff")
myPythonScript.py
看起来是这样的:

python myPythonScript.py

python myOtherScript.py $VarFromFirstScript
print("Running some code...")
VarFromFirstScript = someFunc()
print("Now I do other stuff")
问题是,如何将变量
VarFromFirstScript
返回到调用
myPythonScript.py
的bash脚本


我尝试了
os.environ['VarFromFirstScript']=VarFromFirstScript
,但这不起作用(我假设这意味着python环境与调用bash脚本的环境不同)。

我将为您的脚本提供源代码,这是最常用的方法。这将在当前shell下执行脚本,而不是加载另一个shell。因为它使用相同的shell env变量,所以在退出时可以访问您设置的shell env变量<代码>/path/to/script.sh或
source/path/to/script.sh
都可以工作,
source
有时不工作的地方工作。

您只能将环境变量从父进程传递给子进程

创建子进程时,环境块将复制到子进程-子进程具有副本,因此子进程中的任何更改只会影响子进程的副本(以及它创建的任何其他子进程)

要与父级通信,最简单的方法是在bash中使用命令替换,我们在其中捕获stdout:

Bash脚本:

#!/bin/bash
var=$(python myPythonScript.py)
echo "Value in bash: $var"
#!/bin/bash

while read -r line
do
    if [[ $line = ++++* ]]
    then
        # Strip out the marker
        var=${line#++++}
    else
        echo "$line"
    fi
done < <(python myPythonScript.py)

echo "Value in bash: $var"
Python脚本:

print("Hollow world!")
def someFunc():
    return "Hollow World"

print("Running some code...")

VarFromFirstScript = someFunc()
# Prefix our data with a well-known marker
print("++++" + VarFromFirstScript)

print("Now I do other stuff")
样本运行:

$ bash gash.sh
Value in bash: Hollow world!
如果python中有其他print语句,则需要筛选出所需的数据,可能需要使用已知前缀标记数据

如果python中有许多
print
语句,那么此解决方案是不可伸缩的,因此可能需要使用进程替换,如下所示:

python myPythonScript.py

python myOtherScript.py $VarFromFirstScript
print("Running some code...")
VarFromFirstScript = someFunc()
print("Now I do other stuff")
Bash脚本:

#!/bin/bash
var=$(python myPythonScript.py)
echo "Value in bash: $var"
#!/bin/bash

while read -r line
do
    if [[ $line = ++++* ]]
    then
        # Strip out the marker
        var=${line#++++}
    else
        echo "$line"
    fi
done < <(python myPythonScript.py)

echo "Value in bash: $var"
样本运行:

$ bash gash.sh
Running some code...
Now I do other stuff
Value in bash: Hollow World

不能将环境变量传播到父进程。但您可以打印变量,并从shell中将其重新分配给变量名:

VarFromFirstScript=$(python myOtherScript.py $VarFromFirstScript)
您不得在代码中或使用
stderr

sys.stderr.write("Running some code...\n")
VarFromFirstScript = someFunc()
sys.stdout.write(VarFromFirstScript)
另一种方法是创建一个包含要设置的变量的文件,并让它由shell解析(您可以创建一个shell,父shell将
源代码

shlex.quote
允许避免来自python的代码注入,由Charles Duffy提供)

然后在调用python之后:

source ./shell_to_source.sh

您不能更改其他进程的环境变量。您只能在启动流程时影响它们,因此环境变量不是选项。这就剩下了IPC的各种其他方式,但最自然的方式可能是写入
stdout
。因此,考虑到python脚本有一堆print语句,我只需在bash中解析所有这些语句,就可以得到我想要的
export
语句了。为什么它会有这些
print()
调用(不是语句,不是在Python 3中!)?我猜它是用于日志记录的,对吗?在这种情况下,首先,使用日志库,然后也可以使用它来记录到文件。其次,不要使用stdout,而是使用stderr,它通常用于非有效负载的非正式输出。如果该代码只是一个shell脚本。但是,您不能编写Python代码。确实,请使用子流程来创建bash env v可以从python脚本中更改吗?据我所知,BASH已经作为父进程运行,无法更改另一个进程的环境变量。这应该是
pipes.quote(VarFromFirstScript)
(或者在python 3中,
shlex.quote(…)
)要避免安全问题。向STDUT写入也是常见的——请考虑<代码> SSH代理< /C>如何输出其调用的W/<代码> EVE“$(SSH代理-S)”。
。建议写入文件和
source
文件在这里似乎是不必要的。好的,但是这个方法允许更改几个变量。我不确定我是否理解你在那里说的话。
eval
方法和
source
方法在这方面是相同的;
ssh-agent
肯定会设置m不止一个变量。请记住,您可以
eval
使用包含文字换行符的代码的字符串。