Local variables after loop exit

前端 未结 5 650
眼角桃花
眼角桃花 2021-01-03 13:50

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
cat          


        
相关标签:
5条回答
  • 2021-01-03 14:08

    Here's a one liner in awk.

    $ awk 'length>t{t=length}END{print t}' file
    6
    
    0 讨论(0)
  • 2021-01-03 14:09

    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
    
    0 讨论(0)
  • 2021-01-03 14:09
    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
    
    0 讨论(0)
  • 2021-01-03 14:14

    A pipe starts a new subshell, with its own environment and variable space. Use < tmp at the end of the loop instead.

    0 讨论(0)
  • 2021-01-03 14:15

    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
    
    0 讨论(0)
提交回复
热议问题