2013-08-28 8 views
1

У меня есть больший сценарий, но это меньше, один показывает проблему:Почему эта переменная не изменяется?

#!/bin/bash 
x=0 
if [[ $x == 0 ]] 
then 
    ls | while read L 
    do 
    x=5 
    echo "this is a file $L and this is now set to five --> $x" 
    done 
fi 
echo "this should NOT be 0 --> $x" 

Если переменная установлена ​​за пределами цикла в то время, то он работает, как я ожидал. Версия bash - 3.2.25 (1) -release (x86_64-redhat-linux-gnu). Я буду чувствовать себя таким глупым, если это будет какая-то очевидная вещь.

+0

Это общий вопрос. Read faq: http://mywiki.wooledge.org/BashFAQ/024 –

+0

Еще одна отличная ссылка: [Почему вы не должны разбирать выходные данные ls] (http://mywiki.wooledge.org/ParsingLs) –

+0

Проверьте это как thread: http://stackoverflow.com/questions/13233452/bash-variable-change-doesnt-persist. – konsolebox

ответ

3

Значение x, установленное в 5, находится в под-оболочке (поскольку оно является частью конвейера), а то, что происходит в под-оболочке, не влияет на родительскую оболочку.

Вы можете избежать подоболочку и получить результат вы рассчитывали, используя подстановку процесса в bash:

#!/bin/bash 
x=0 
if [[ $x == 0 ]] 
then 
    while read L 
    do 
    x=5 
    echo "this is a file $L and this is now set to five --> $x" 
    done < <(ls) 
fi 
echo "this should NOT be 0 --> $x" 

Теперь петля while является частью основного процесса оболочки (только ls в суб -process), поэтому изменяется переменная x.

Мы можем обсудить достоинства разбора вывода ls в другой раз; в значительной степени это связано с вопросом в вопросе.

Другой вариант:

#!/bin/bash 
x=0 
if [[ $x == 0 ]] 
then 
    ls | 
    { 
    while read L 
    do 
    x=5 
    echo "this is a file $L and this is now set to five --> $x" 
    done 
    echo "this should NOT be 0 --> $x" 
    } 
fi 
echo "this should be 0 still, though --> $x" 
+0

Ой! Как смущающе. Спасибо Алексу Даниэлю Якименко и Джонатану Леффлеру. – Allen

Смежные вопросы