shell脚本中使用了管道符,导致变量赋值丢失的原因
2010-12-18 11:38
771 查看
发现这个问题来自对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
#!/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
相关文章推荐
- shell脚本中赋值给变量中有空格, 导致命令执行失败
- shell 脚本:使用过程中使得变量能够赋值
- Shell 脚本分割变量分别赋值与sed 应用打印特殊行
- Shell脚本基础 、 使用变量 、 条件测试及选择 、 列表式循环
- shell脚本的变量赋值
- shell 脚本变量赋值
- 如何在shell脚本中使用变量
- shell脚本获取一个文件的行数赋值给变量
- 使用移位运算的时候,没有把最终的值重新赋值到原变量,导致死循环
- shell脚本的使用---if变量编写lamp管理脚本
- Shell脚本定义变量和重新赋值
- shell脚本标准输出赋值给变量
- 在Yii2中使用Pjax导致Yii2内联脚本载入失败的原因分析
- shell脚本的作用,shell脚本变量的定义和三种赋值方式【shell脚本的学习笔记一】
- crontab中使用环境变量的方法(手动执行shell脚本可以,在定时任务中不行)
- shell 脚本中将输出内容赋值给一个变量时的换行问题
- shell 脚本 变量赋值
- shell脚本——变量的设置及使用
- linux命令行与shell脚本大全_第五章_使用环境变量
- shell脚本中使用tr命令实现对字符串删除、替换和赋值