Local variables after loop exit
I am having some issues with local variables after exiting a loop. The variable max
ends up with the value 0, despite the code below:
max=0
ca开发者_运维问答t 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
And this is the output I receive:
5
6
tmp 0
I don't understand why max
is 0 after exiting the loop, while inside the loop it finds the correct values.
A pipe starts a new subshell, with its own environment and variable space. Use < tmp
at the end of the loop instead.
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
According to the bash man page each command in a pipeline is executed in a subshell. That is, your while loop runs in a subshell and only the value of the variable max in that subshell is modified.
Variables of subshells are not propagated back to the calling shell, which is running the echo command and thus still sees the initial zero value.
If you run the echo in the same subshell (note the curly braces) it will work:
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
}
If you need the value for further calculations in the outer shell, you would need to use command substitution like this:
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
The pipe before your while is putting everything inside the loop into a separate shell, and thus a separate identifier context (essentially a new environment).
Redirecting the tmp
file into the while
loop via <
will keep your loop and variables all in the same execution context.
while read line
do
# your loop stuff
done < tmp
Here's a one liner in awk.
$ awk 'length>t{t=length}END{print t}' file
6
精彩评论