Локальные переменные после выхода из цикла - PullRequest
2 голосов
/ 13 января 2010

У меня возникли проблемы с локальными переменными после выхода из цикла. Переменная 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 ]

13 голосов
/ 13 января 2010

Труба запускает новую подоболочку с собственным окружением и переменным пространством. Вместо этого используйте < tmp в конце цикла.

3 голосов
/ 14 января 2010

Согласно справочной странице bash каждая команда в конвейере выполняется в подоболочке. То есть ваш цикл while выполняется в подоболочке, и изменяется только значение переменной max в этой подоболочке.

Переменные подоболочек не передаются обратно вызывающей оболочке, которая выполняет команду 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 голосов
/ 13 января 2010
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
1 голос
/ 13 января 2010

Канал перед вашим временем помещает все внутри цикла в отдельную оболочку и, таким образом, в отдельный контекст идентификатора (по сути, новую среду).

Перенаправление файла tmp в цикл while с помощью < сохранит цикл и переменные в одном контексте выполнения.

while read line
do
    # your loop stuff 
done < tmp
0 голосов
/ 14 января 2010

Вот один вкладыш в awk.

$ awk 'length>t{t=length}END{print t}' file
6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...