管道下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
[root@vm_102 ~] # cat config.ini
test
[root@vm_102 ~] # ./a.sh 
test
  mark

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

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

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

1
2
3
4
5
6
7
8
9
10
11
[root@vm_102 ~] # cat a.sh 
#!/bin/sh
while  read  var
do
export  a=$var
echo  $a
done  < config.ini
echo  "$a mark"
[root@vm_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
[root@vm_102 ~] # cat a.sh 
#!/bin/ksh
cat  config.ini |  while  read  var
do
export  a=$var
echo  $a
done
echo  "$a mark"
[root@vm_102 ~] # ./a.sh 
test
test  mark


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



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


     本文转自1321385590 51CTO博客,原文链接:http://blog.51cto.com/linux10000/1972783,如需转载请自行联系原作者





相关文章
|
3月前
|
小程序
小程序for循环中key值的作用?
小程序for循环中key值的作用?
|
3月前
|
Perl
在awk中,初始化-测试-递增型的 `for` 循环
在awk中,初始化-测试-递增型的 `for` 循环
20 2
|
9月前
判断变量是否为数组的几种方法
判断变量是否为数组的几种方法
97 0
|
9月前
三个线程循环顺序打印
三个线程循环顺序打印
49 0
|
10月前
|
Python
#PY小贴士# for 循环定义的变量,循环外可以用吗?
我们知道,在 python 中要获取一个变量的值,必须是先给它赋值过,不然就是未定义。那么这个 i,代码中没有显式的赋值,在循环体之外还可以用吗?
|
JavaScript 前端开发
不同类型的循环
不同类型的循环
56 0
|
JavaScript 前端开发
使用语句 1 来初始化循环中所使用的的变量
使用语句 1 来初始化循环中所使用的的变量
48 0
定义函数,并用指针交换两个变量内容(正确版和错误版+错误原因)
定义函数,并用指针交换两个变量内容(正确版和错误版+错误原因)
65 0
定义函数,并用指针交换两个变量内容(正确版和错误版+错误原因)
|
Java Shell Linux
Shell流程控制(重点)、if 判断、case 语句、let用法、for 循环中有for (( 初始值;循环控制条件;变量变化 ))和for 变量 in 值 1 值 2 值 3… 、while 循环
Shell流程控制(重点)、if 判断、case 语句、let用法、for 循环中有for (( 初始值;循环控制条件;变量变化 ))和for 变量 in 值 1 值 2 值 3… 、while 循环
Shell流程控制(重点)、if 判断、case 语句、let用法、for 循环中有for (( 初始值;循环控制条件;变量变化 ))和for 变量 in 值 1 值 2 值 3… 、while 循环
【Groovy】循环控制 ( Number 注入函数实现循环 | times 函数 | upto 函数 | downto 函数 | step 函数 | 闭包作为最后参数可写在外面 )(二)
【Groovy】循环控制 ( Number 注入函数实现循环 | times 函数 | upto 函数 | downto 函数 | step 函数 | 闭包作为最后参数可写在外面 )(二)
123 0
【Groovy】循环控制 ( Number 注入函数实现循环 | times 函数 | upto 函数 | downto 函数 | step 函数 | 闭包作为最后参数可写在外面 )(二)