循环退出后的局部变量

时间:2010-01-13 20:40:57

标签: bash

退出循环后,我遇到了局部变量的一些问题。变量max最终得到值0,尽管代码如下:

max=0
cat tmp|while read line
do
temp=$(echo $line|tr -d "\n"|wc -c)
if [ $temp -gt $max ];then

max=$temp
echo $max
fi
done
echo -n tmp $max

cat tmp
12345
123456

这是我收到的输出:

5
6
 tmp 0

我不明白为什么max在退出循环后为0,而在循环中它找到正确的值。

5 个答案:

答案 0 :(得分:13)

管道启动一个新的子shell,具有自己的环境和可变空间。改为在循环结束时使用< tmp

答案 1 :(得分:3)

max=0
while read line
do
    temp=$(echo $line|tr -d "\n"|wc -c)
    if [ $temp -gt $max ]
    then 
        max=$temp
        echo $max
    fi
done <tmp
echo -n tmp $max

答案 2 :(得分:3)

根据bash手册页,管道中的每个命令都在子shell中执行。也就是说,你的while循环在子shell中运行,只修改了子shell中变量max的值。

子shell的变量不会传播回调用shell,调用shell运行echo命令,因此仍然可以看到初始零值。

如果你在同一个子shell中运行echo(注意花括号)它将起作用:

max=0
cat tmp|{
    while read line
    do
        temp=$(echo $line|tr -d "\n"|wc -c)
        if [ $temp -gt $max ];then
            max=$temp
        fi
    done
    echo -n tmp $max
}

如果在外壳中需要进一步计算的值,则需要使用如下命令替换:

max=0
max=$(cat tmp|{
    while read line
    do
        temp=$(echo $line|tr -d "\n"|wc -c)
        if [ $temp -gt $max ];then
            max=$temp
        fi
    done
    echo -n $max
})
echo tmp $max

答案 3 :(得分:1)

while之前的管道将循环中的所有内容放入一个单独的shell中,从而形成一个单独的标识符上下文(实际上是一个新环境)。

通过tmpwhile文件重定向到<循环将使您的循环和变量保持在同一个执行上下文中。

while read line
do
    # your loop stuff 
done < tmp

答案 4 :(得分:0)

这是awk中的一个班轮。

$ awk 'length>t{t=length}END{print t}' file
6