管道下while循环中定义的变量在退出while循环时引用为空的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了管道下while循环中定义的变量在退出while循环时引用为空的问题相关的知识,希望对你有一定的参考价值。

最近在编写一个shell脚本的时候,在while循环中定义了一些变量,但是当while退出之后调用这些变量的时候发现,变量值都为空了,折腾了一整天,才找到其原因之所在:

    我在这里只是大致做一个实验,说明下这里问题出在说明地方,开始的时候代码大意就是:

1
2
3
4
5
6
7
#!/bin/sh
cat config.ini | while read var
do
a=$var
echo $a
done
echo "$a mark"
1
2
3
4
5
[[email protected]_102 ~]# cat config.ini
test
[[email protected]_102 ~]# ./a.sh 
test
 mark

    这个时候我们发现,在while循环中定义好的变量,为什么在while循环退出后变量值却为空了呢,会不会是局部变量的问题导致的呢,这里使用export试下:

1
2
3
4
5
6
7
8
9
10
11
[[email protected]_102 ~]# cat a.sh 
#!/bin/sh
cat config.ini | while read var
do
export a=$var
echo $a
done
echo "$a mark"
[[email protected]_102 ~]# ./a.sh
test
 mark

依然不行,于是开始了漫长的Google之旅,后来发现,这里是因为管道符重定向导致的,先把代码改下试试看:

1
2
3
4
5
6
7
8
9
10
11
[[email protected]_102 ~]# cat a.sh 
#!/bin/sh
while read var
do
export a=$var
echo $a
done < config.ini
echo "$a mark"
[[email protected]_102 ~]# ./a.sh 
test
test mark

成功!!!!!!!!

    这里为什么会出现这种问题呢,其实原因很简单,当bash在使用管道符的时候,会产生subshell,从而使在这个subshell中对变量的赋值只在自身的subshell中生效,不会影响到shell脚本本身的进程。

    但是ksh现在有个feature,能使管道中对变量的赋值反映到父shell中来,这就是网上有人问说这样的代码在k shell中就是OK的原因。 

    所以这里如果我们使用ksh的话就可以打印出变量的变量值:

1
2
3
4
5
6
7
8
9
10
11
[[email protected]_102 ~]# cat a.sh 
#!/bin/ksh
cat config.ini | while read var
do
export a=$var
echo $a
done
echo "$a mark"
[[email protected]_102 ~]# ./a.sh 
test
test mark


本文出自 “红楼遗梦” 博客,请务必保留此出处http://leidongya.blog.51cto.com/7375845/1588066



参考博文:http://leidongya.blog.51cto.com/7375845/1588066

以上是关于管道下while循环中定义的变量在退出while循环时引用为空的问题的主要内容,如果未能解决你的问题,请参考以下文章

六十九for循环while循环break跳出循环continue结束本次循环exit退出整

bash的循环中无法保存变量

无限循环计算阶乘问题

Shell while循环语句中的陷阱

while语句

Python 循环语句