无法使用Python修改环境变量(在Shell脚本中分配)

时间:2017-05-04 04:31:51

标签: python python-3.x shell environment-variables sh

我试图在Shell脚本中创建一个循环,当我在特定字符串中找到一个不同于0的整数(使用Python)时,我想要打破循环并完成shell脚本执行。问题是甚至在该特定字符串中第一次出现一个不同于0的整数后,shell脚本继续执行。我试图通过回显GET_OUT_OF_LOOP的值来调试它,但它只是在找到我正在查找的整数类型后仍保持回显0对于。我已经在网上寻找一种方法来做到这一点,但我仍然没有弄明白...... 这是我的shell脚本:

#!/bin/sh                                                                                                                                             


export GET_OUT_OF_LOOP=0                                                                                                                              

while [  $GET_OUT_OF_LOOP -ne 1 ]; do                                                                                                                                                                                                                                                              
    python3 provas.py provas.txt                                                                                                                      
    ./provas < provas.txt >> data.txt                                                                                                                 
    python3 test.py data.txt                                                                                                                          
    sh clear_data.sh                                                                                                                                  

done

这是我的Python代码(test.py),我试图使用os.environ更改GET_OUT_OF_LOOP变量的值:

#!usr/env/bin python3                                                                                                                                 
import sys                                                                                                                                            
import os                                                                                                                                             
import re                                                                                                                                             
script, filename = sys.argv                                                                                                   
os.environ['GET_OUT_OF_LOOP'] = '0'                                                                                                                   

fin = open("data.txt", 'r')                                                                                                                           

for line in fin:                                                                                                                                      
    if "A percentagem de aprovação foi de" in line:                                                                                                   
        if int(re.search(r'\d+', line).group()) != 0:                                                                                                 
            print(line)                                                                                                                               
            os.environ['GET_OUT_OF_LOOP'] = '1'

3 个答案:

答案 0 :(得分:2)

python进程是shell进程的子进程,它不能修改其父进程的环境变量。

对于您的情况,您可以使用退出代码传递消息;即。

shell脚本:

python3 test.py data.txt || GET_OUT_OF_LOOP=1

蟒:

#!usr/env/bin python3                                                                                                                              
import sys                                                                                                                                         
import os                                                                                                                                          
import re                                                                                                                                          
script, filename = sys.argv
fin = open("data.txt", 'r')                                                                                                                        

for line in fin:                                                                                                                                   
    if "A percentagem de aprovação foi de" in line:                                                                                                
        if int(re.search(r'\d+', line).group()) != 0:                                                                                              
            print(line)                                                                                                                            
            sys.exit(1)
sys.exit(0)

答案 1 :(得分:1)

这就是环境变量的工作方式:您可以在子流程中更改调用它的流程环境中的变量。 (在shell脚本中,几乎所有代码行,但对于控制结构,都是外部子进程)

您可以拥有的是子进程的简单无符号字节返回值,可以在shell脚本中作为隐式$?变量读取。

在Python的情况下,您可以通过调用sys.exit()来终止带有此返回值的程序

因此,在shell脚本中,您可以执行此操作来分配变量:

python3 test.py data.txt 
GET_OUT_OF_LOOP=$?

Python脚本中的Python改变了:

os.environ['GET_OUT_OF_LOOP'] = '1'

sys.exit(1)

当然,如果你只是从顶部使用Python,它会更加理智和可维护 - stdlib中的shutils模块可以轻松复制文件,最重要的是,在脚本的所有行中获得一致的语法,更容易使用比较运算符和变量。

答案 2 :(得分:0)

以下是两个类似的stackoverflow问题,可以解释你的问题:

how-do-i-make-environment-variable-changes-stick-in-python

environment-variables-in-python-on-linux

因此导致此问题的真正原因是,当我们运行一个进程时,进程更改的环境变量仅在进程运行时期间可用,它不会更改外部变量,这里是您的简化脚本证明:

#test.py
import os
os.environ['test_env_var'] = '1'

#test.sh
export test_env_var=0                                                                                                                              

while [  $test_env_var -ne 1 ]; do                                                                             
    python test.py
    echo $test_env_var
done

你可能已经看到了即将发生的事情,这个循环将永远回显$ tev为0。 因此,根据我的理解解决这个问题的解决方案是,如果有必要,可以将更改外包到外部系统文件中。将更改附加到相关系统的配置文件中,例如,如果您是linux bash用户,可以将“export test_env_var = 1”附加到〜/ .bashrc中。