shell脚本中使用了管道符,导致变量赋值丢失的原因

发现这个问题来自对SGE的startmpi.sh脚本做改造的时候。考虑如下一段shell代码: 
# !/bin/sh
# declare -i i


testline
= " hello: "

cat testfile 
|   while   read  line;  do
   testline
= " ${testline}${line}  "
   echo 
" In cycle, the testline is: $testline "

#  for (( i=0; i<3; i++ )) do
#    testline="${testline}${i} "

#i=0
#while [ $i -lt 3 ]; do
#   testline="${testline}${i} "
#   i=$i+1


done
echo 
$testline

 

 代码中用到的testfile可以是任何文本的文件,比如: 


phy2 2 
phy3 2 
phy4 2 

这样的情况下,代码运行的结果出乎我的意料,testline这个变量在while循环中就好像没有被赋过值一样,输出是这样的: 

In cycle, the testline is: hello:phy2 2 
In cycle, the testline is: hello:phy2 2 phy3 2 
In cycle, the testline is: hello:phy2 2 phy3 2 phy4 2 
hello: 

这是为什么呢?参考上面的代码,如果把cat testfile | while read line; do这一段注释掉,打开for循环那一段,或打开while循环那一段的话,testline就都能在循环中被赋值,最后的echo $testline就是正确的。这是为什么呢? 

最后发现是管道符|引发的问题。原因非常简单,之前在学习shell的时候就学过shell执行命令的原理,里面也有对管道的描述。简单来说,在shell中使用管道符号,会产生subshell,从而使在这个subshell中对变量的赋值只在subshell中生效,不会影响到shell脚本本身的进程。 

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

附上网上搜来的一篇文章,讲解的不错。

 /Files/super119/bash_pipe_variable_lost.mht.zip

转载于:https://www.cnblogs.com/super119/archive/2010/12/18/1909829.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值