Shell脚本循环修改全局变量报错:为何出现‘0=Done: command not found’?
首先看你遇到的报错:/tmp/test: line 4: 0=Done: command not found,这是因为你赋值变量的写法完全错了!
在Shell里,给变量赋值的时候绝对不能加美元符号$——$a是用来读取变量a当前值的语法,你写$a="Done"相当于把a的当前值(也就是0)和="Done"拼在一起,变成了0=Done,Shell会把这个当成一个命令去执行,自然就报错了。
第一步:修正赋值语法
把$a="Done"改成a="Done",这才是Shell变量赋值的正确姿势。
第二步:调整脚本逻辑(让echo能执行)
你原来的脚本里,exit语句放在循环内部,执行后整个脚本直接退出,后面的echo $a根本没机会运行。如果想要输出Done,可以把echo放到exit之前,或者调整循环终止条件(毕竟你的while [ true ]是死循环,不加exit会一直跑)。
修正后的脚本可以是这样:
a="0" while [ true ]; do a="Done" # 正确赋值,去掉多余的$ echo $a # 在退出前输出变量值 exit # 退出脚本,终止死循环 done
执行这个脚本就会输出你想要的Done了。
关于循环中修改全局变量的问题
在Shell的普通循环(比如你这里的while循环)里,变量默认就是全局的——也就是说你在循环里修改的变量,在循环外面也能正常访问到。举个简单例子:
count=0 while [ $count -lt 3 ]; do count=$((count + 1)) # 循环内修改全局变量 echo "当前count值:$count" done echo "循环结束后count值:$count"
执行后会输出:
当前count值:1 当前count值:2 当前count值:3 循环结束后count值:3
这里count在循环里的修改,在循环外依然能拿到最新结果。
唯一需要注意的例外情况:如果循环是通过管道启动的(比如cat test.txt | while read line; do ...),这时候循环会在子shell里运行,子shell里的变量修改不会同步到父shell的全局变量。但你的脚本是普通的while [ true ]; do结构,完全不存在这个问题,只要赋值语法正确,就能正常修改全局变量。
内容的提问来源于stack exchange,提问作者Sandra Schlichting

