Linux - bash while subshell中变量操作的问题

Posted 王万林 Ben

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux - bash while subshell中变量操作的问题相关的知识,希望对你有一定的参考价值。

Linux - bash while subshell中变量操作的问题

需求

演示一个简单的需求:使用bash语言,对1到5进行累加,并输出结果。

代码

$ cat while_loop_operate_global_variable.sh
#!/bin/bash
# Author: thesre
# Date: 

total=0
echo "Let's check the initial value of total:"
echo "$total"
echo ""

num_list=`seq 1 5`

echo "$num_list"| while read i
do
    total=`echo $total + $i| bc`
    echo $total
done
echo ""
echo "OK, let's check the value of total out of the while loop."
echo $total

Run结果

[thesre@centos8 ~]$ ./while_loop_operate_global_variable.sh
Let's check the initial value of total:
0

1
3
6
10
15

OK, let's check the value of total out of the while loop.
0

可以看到,在while loop中有对变量进行累加。但,最终结果,却是初始值0!

这是为何?

分析

这是因为while运行在subshell里,当while运行完后,其里面的变量被废弃。因此在最后打印的还是初始值。

解决

要解决该问题,需要避免在subshell中操作变量。

方法一:我们可以使用here string的方式来让操作变量的代码放在脚本main shell中。

[thesre@centos8 ~]$ cat while_loop_operate_global_variable.sh
#!/bin/bash
# Author: thesre
# Date: 

total=0
echo "Let's check the initial value of total:"
echo "$total"
echo ""

num_list=`seq 1 5`

while read i
do
    total=`echo $total + $i| bc`
    echo $total
done <<< "$num_list"

echo ""
echo "OK, let's check the value of total out of the while loop."
echo $total

方法二:我们可以使用process substitution的方式来让操作变量的代码放在脚本main shell中。

#!/bin/bash
# Author: thesre
# Date: 

total=0
echo "Let's check the initial value of total:"
echo "$total"
echo ""

while read i
do
    total=`echo $total + $i| bc`
    echo $total
done < <(seq 1 5)

echo ""
echo "OK, let's check the value of total out of the while loop."
echo $total

Run效果

[thesre@centos8 ~]$ ./while_loop_operate_global_variable.sh
Let's check the initial value of total:
0

1
3
6
10
15

OK, let's check the value of total out of the while loop.
15

总结

在脚本程序出现不符合预期的情况时,需分析进程间的关系。如本案,操作变量的代码在subshell中,无论如何操作都不会影响在main shell中的变量。

参考资料

https://tldp.org/LDP/abs/html/gotchas.html#BADREAD0 #管道输出到任一命令均会有该问题
https://tldp.org/LDP/abs/html/process-sub.html #process substitution

以上是关于Linux - bash while subshell中变量操作的问题的主要内容,如果未能解决你的问题,请参考以下文章

Linux的shell脚本实战之while循环

Linux shell语言——dash和bash

Linux命令:break,continue,while

bash常用命令

linux下 bash_profile和bashrc区别

Linux系统shell脚本之while循环实践1