简体   繁体   English

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

[英]Can't modify environment variable(assigned in Shell Script) using Python

I'm trying to create a loop inside a Shell Script and I want to break out of the loop and finish the shell script execution when i find an integer different than 0 in a specific string(using Python).The problem is even after the first occurrence of an integer different than 0 in that specific string the shell script keeps executing.I tried to debug it by echoing the value of GET_OUT_OF_LOOP but it just keeps echoing 0 even after finding the kind of integer I was looking for. 我正在尝试在Shell脚本中创建一个循环,当我在特定字符串中找到一个不同于0的整数时(使用Python),我想打破循环并完成Shell脚本的执行。 shell脚本一直在执行该特定字符串中首次出现一个不同于0的整数。我试图通过回显GET_OUT_OF_LOOP的值来对其进行调试,但是即使找到了我想要的整数,它也一直保持回显0。 I already looked on the web for a way to do this but I still didn't figure it out... Here's my shell script: 我已经在网上寻找实现此目的的方法,但是我仍然没有弄清楚……这是我的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

And here is my Python code(test.py) where I'm trying to change the value of the GET_OUT_OF_LOOP variable using os.environ : 这是我的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'

The python process is a subprocess of the shell process, and it can not modify environment vars of its parent process. python进程是shell进程的子进程,它不能修改其父进程的环境变量。

For your case, you can use the exit code to pass the message; 对于您的情况,您可以使用退出代码来传递消息。 ie

shell script: 外壳脚本:

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

python: 蟒蛇:

#!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)

That is just the way environment variables work: you can't in a sub-process change variables in the environment of the process which called it. 这就是环境变量的工作方式:您不能在子流程中更改调用它的流程环境中的变量。 (And in shell script, almost all lines of code, but for control structures, are external sub-processes) (在shell脚本中,几乎所有代码行,但对于控制结构,都是外部子进程)

What you can have is a simple unsigned byte return value of your sub-process that can be read in the shell script as the implicit $? 您可以拥有的是子进程的简单无符号字节返回值,该值可以在shell脚本中作为隐式$?读取$? variable. 变量。

In Python's case, you terminate the program with this return value by calling sys.exit() 在Python的情况下,您可以通过调用sys.exit()使用此返回值终止程序。

So, in your shell script you can do this to assign the variable: 因此,在您的shell脚本中,您可以执行以下操作来分配变量:

python3 test.py data.txt 
GET_OUT_OF_LOOP=$?

And the Python in the Python script change: 并且Python脚本中的Python发生了变化:

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

for 对于

sys.exit(1)

Of course, it would be much more sane and maintainable if yu just use Python all the way from the top - the shutils module in the stdlib makes it easy to copy files around, and you, above all, get a consistent syntax across all lines of your script, much easier to use comparison operators and variables. 当然,如果yu从头开始一直使用Python,它将更加理智和可维护shutils中的shutils模块使复制文件变得容易,而且最重要的是,您在所有行上都获得了一致的语法脚本,使用比较运算符和变量要容易得多。

Here are two similar stackoverflow questions that might explain yours: 这是两个类似的stackoverflow问题,可能会解释您的问题:

how-do-i-make-environment-variable-changes-stick-in-python 我如何使环境变量在python中变化

environment-variables-in-python-on-linux Linux上的Python中的环境变量

So the real reason causing this issue is that when we run a process, the environment variables being changed by the process are only available during the process runtime, it won't change the external variables, here is a simplified script of yours to prove it: 因此,导致此问题的真正原因是,当我们运行一个流程时,该流程所更改的环境变量仅在流程运行时才可用,而不会更改外部变量,这里有一个简化的脚本来证明这一点。 :

#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

As you might have already seen what's coming, the loop will echo $tev to be 0 forever. 您可能已经看到了即将发生的情况,该循环将回显$ tev永远为0。 Hence the solution to solve this problem to my understanding, would be to out-source the change into the external system files, if it's necessary. 因此,据我所知,解决此问题的解决方案是,如有必要,将更改外包给外部系统文件。 Append changes to the configuration files of the regarding systems, for instance of this example, you can append "export test_env_var=1" into ~/.bashrc, if you are a linux bash user. 附加对相关系统的配置文件的更改,例如,在本示例中,如果您是linux bash用户,则可以将“ export test_env_var = 1”附加到〜/ .bashrc中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM