在python中设置调用bash脚本的环境变量[复制]

时间:2022-05-14 11:41:58

This question already has an answer here:

这个问题在这里已有答案:

I have a bash script that looks like this:

我有一个看起来像这样的bash脚本:

python myPythonScript.py

python myOtherScript.py $VarFromFirstScript

and myPythonScript.py looks like this:

和myPythonScript.py看起来像这样:

print("Running some code...")
VarFromFirstScript = someFunc()
print("Now I do other stuff")

The question is, how do I get the variable VarFromFirstScript back to the bash script that called myPythonScript.py.

问题是,如何将变量VarFromFirstScript返回到调用myPythonScript.py的bash脚本。

I tried os.environ['VarFromFirstScript'] = VarFromFirstScript but this doesn't work (I assume this means that the python environment is a different env from the calling bash script).

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

3 个解决方案

#1


1  

you cannot propagate an environment variable to the parent process. But you can print the variable, and assign it back to the variable name from your shell:

您无法将环境变量传播到父进程。但是您可以打印变量,并将其从shell分配回变量名称:

VarFromFirstScript=$(python myOtherScript.py $VarFromFirstScript)

you must not print anything else in your code, or using stderr

您不得在代码中或使用stderr打印任何其他内容

sys.stderr.write("Running some code...\n")
VarFromFirstScript = someFunc()
sys.stdout.write(VarFromFirstScript)

an alternative would be to create a file with the variables to set, and make it parse by your shell (you could create a shell that the parent shell would source)

另一种方法是创建一个包含要设置的变量的文件,并使其由shell解析(您可以创建一个父shell将提供的shell)

import shlex
with open("shell_to_source.sh","w") as f:
   f.write("VarFromFirstScript={}\n".format(shlex.quote(VarFromFirstScript))

(shlex.quote allows to avoid code injection from python, courtesy Charles Duffy)

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

then after calling python:

然后在调用python之后:

source ./shell_to_source.sh

#2


1  

You can only pass environment variables from parent process to child.

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

When the child process is created the environment block is copied to the child - the child has a copy, so any changes in the child process only affects the child's copy (and any further children which it creates).

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

To communicate with the parent the simplest way is to use command substitution in bash where we capture stdout:

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

Bash script:

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

Python script:

print("Hollow world!")

Sample run:

$ bash gash.sh
Value in bash: Hollow world!

You have other print statements in python, you will need to filter out to only the data you require, possibly by marking the data with a well-known prefix.

你在python中有其他的print语句,你需要过滤掉你需要的数据,可能是用一个众所周知的前缀标记数据。

If you have many print statements in python then this solution is not scalable, so you might need to use process substitution, like this:

如果你在python中有很多print语句,那么这个解决方案是不可扩展的,所以你可能需要使用进程替换,如下所示:

Bash script:

#!/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 script:

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

Sample Run:

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

#3


-2  

I would source your script, this is the most commonly used method. This executes the script under the current shell instead of loading another one. Because this uses same shell env variables you set will be accessible when it exits. . /path/to/script.sh or source /path/to/script.sh will both work, . works where source doesn't sometimes.

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

#1


1  

you cannot propagate an environment variable to the parent process. But you can print the variable, and assign it back to the variable name from your shell:

您无法将环境变量传播到父进程。但是您可以打印变量,并将其从shell分配回变量名称:

VarFromFirstScript=$(python myOtherScript.py $VarFromFirstScript)

you must not print anything else in your code, or using stderr

您不得在代码中或使用stderr打印任何其他内容

sys.stderr.write("Running some code...\n")
VarFromFirstScript = someFunc()
sys.stdout.write(VarFromFirstScript)

an alternative would be to create a file with the variables to set, and make it parse by your shell (you could create a shell that the parent shell would source)

另一种方法是创建一个包含要设置的变量的文件,并使其由shell解析(您可以创建一个父shell将提供的shell)

import shlex
with open("shell_to_source.sh","w") as f:
   f.write("VarFromFirstScript={}\n".format(shlex.quote(VarFromFirstScript))

(shlex.quote allows to avoid code injection from python, courtesy Charles Duffy)

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

then after calling python:

然后在调用python之后:

source ./shell_to_source.sh

#2


1  

You can only pass environment variables from parent process to child.

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

When the child process is created the environment block is copied to the child - the child has a copy, so any changes in the child process only affects the child's copy (and any further children which it creates).

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

To communicate with the parent the simplest way is to use command substitution in bash where we capture stdout:

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

Bash script:

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

Python script:

print("Hollow world!")

Sample run:

$ bash gash.sh
Value in bash: Hollow world!

You have other print statements in python, you will need to filter out to only the data you require, possibly by marking the data with a well-known prefix.

你在python中有其他的print语句,你需要过滤掉你需要的数据,可能是用一个众所周知的前缀标记数据。

If you have many print statements in python then this solution is not scalable, so you might need to use process substitution, like this:

如果你在python中有很多print语句,那么这个解决方案是不可扩展的,所以你可能需要使用进程替换,如下所示:

Bash script:

#!/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 script:

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

Sample Run:

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

#3


-2  

I would source your script, this is the most commonly used method. This executes the script under the current shell instead of loading another one. Because this uses same shell env variables you set will be accessible when it exits. . /path/to/script.sh or source /path/to/script.sh will both work, . works where source doesn't sometimes.

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