10.02.2009 01:58

zbПодводные камни в циклах bash

Сегодня я хотел бы рассказать о возможных подводных камнях и их обходе при написании скриптов на bash.



while;do : ;done

обычно я использую цикл while в случае когда требуется обработка строк разделенных пробелами (в отличии от for, см. ниже)

но это не единственное различие for и while в bash. приведу простой пример



 1
2
3
4
5
6
7
8
9
10
11
echo -e 'test test\ntest2\ntest3  test3'|

while read a ;do

echo ==$a

exit

done

echo "the script finished $a"



Здесь я хотел бы обратить внимание на то, как распределятся процессы при выполнении кода, ветки основного процесса я помечу курсивом, а ветки потомка выделю жирным



echo -e 'test test\ntest2\ntest3 test3'|

while read a ;do

echo ==$a

exit

done


echo "the script finished $a"



таким образом становится понятно, что цикл выйдет напечатав

test test

, но переменная $a останется необновленной, к тому же exit в конце выйдет всего-лишь из цикла. поэтому последняя строка вывода будет

the script finished

попробуем написать скрипт основаный на while, который напечатает все строки а в конце получит в управление переменную заданную в теле цикла., так-же выведет было ли выполнение цикла вообще.



все гораздо проще чем кажется мы просто перенесем echo в дочерний процесс избавившись от перенаправления через pipe:

while read a ;do

echo ==$a

flag=1

done < <(
echo -e 'test test\ntest2\ntest3 test3')

if < $flag > ;then echo "the script finished, loop completed $a" else

echo "the script finished, loop didn't started";

fi

exit 0





2. for a in $list ;do : ;done

часто for удобнее чем while но только в случае когда $list (обычно вывод комманды) не содержит пробелов, или, если нам на это плевать.



тут есть свои приколы, но чет я устал и не могу найти пример, кроме vzctl exec для этого случая.


Тэги: bash script
+ 5 -
Похожие Поделиться

l1feh4ck3r 10.02.2009 12:09 #
Даешь еще статьи по программированию в баше )
geLoni_eL 12.02.2009 02:51 #
тут есть функция в избраное??? что то я найти немогу
nvbn 12.02.2009 03:40 #
Я буду ответственно относиться к безопасности своих приложений.
exelens 12.02.2009 09:10 #
=))) согласен
geLoni_eL 13.02.2009 04:02 #
а я не про браузер
zb 12.02.2009 15:47 #
тут на хабре ответ на эту статью был, через переменную $IFS можно менять разделители, но это тоже не всегда подходит, например
while read a b c
for
не очень легко заменяет, да и для однострочников не годится.