Недавно столкнулся с такой вот загадочной траблой BASH'а, что заставило меня крепко призадуматься над тем, каким же всё-таки образом во встроенном языке оболочки создаются "вложенные" области видимости переменных...
Вот вам классический пример кода, который приводит к, мягко говоря, неожиданному результату:
cnt=0; echo "Before: $cnt"
cat /etc/fstab | \
while read l; do
((cnt++))
echo $cnt
done
echo "After: $cnt"
Перед циклом обнуляем значение переменной-счётчика, дальше на каждой новой итерации цикла наращиваем его и посылаем значение в stdout, затем после выхода из цикла печатаем результирующее значение счётчика, и... упс, а оно обнулилось!!!
Пожалуйста, объясните мне кто-нибудь, почему, собственно, так происходит в BASH - ведь цикл в меру моего разумения данного вопроса должен относиться к той же области видимости, что и echo в конце???
Re: Обнуление переменной на выходе из цикла #1
Для создания анонимного канала выполняется fork, т.е. изменение cnt происходит в дочернем процессе. Мы имеем две переменных в разных процессах.
решается переопределением stdin для while:
или неявное создание именованного канала <(command):
либо явно:
Поехали!
JID: konst.su [обезьяна] gmail.com
Re: Обнуление переменной на выходе из цикла #2
Спасибо, ks, за столь подробный и обстоятельный ответ. Лишний раз убедился в том, что хотя на языке командной оболочки можно делать всё, у скриптового программирования есть, к сожалению, множество "подводных камней", котороые возникают из-за того, что BASH - всё-таки не полноценный язык, подобный Perl, а скорее просто надстройка командной строки.
Эй, оператор-астроном,
Нет звёзд и звёздных глаз -
Есть плац, пивная, гастроном
И горы из колбас!
Марк Мерман, "Никто кино так не снимал, как Лени Риффеншталь"
Обнуление переменной на выходе из цикла #3