我试图在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'
答案 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中。