10.02.09 01:58

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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 для этого случая.


Теги:

KerneL 10.02.09 06:32 # +1
О, спасибо =)
l1feh4ck3r 10.02.09 12:09 # +2
Даешь еще статьи по программированию в баше )
geloni_el 12.02.09 02:51 # +0
тут есть функция в избраное??? что то я найти немогу
nvbn 12.02.09 03:40 # +-1
Я буду ответственно относиться к безопасности своих приложений.
exelens 12.02.09 09:10 # +-3
=))) согласен
geloni_el 13.02.09 04:02 # +0
а я не про браузер
zb 12.02.09 15:47 # +0
тут на хабре ответ на эту статью был, через переменную $IFS можно менять разделители, но это тоже не всегда подходит, например
while read a b c
for
не очень легко заменяет, да и для однострочников не годится.
Посты Комментарии
Последние посты
Посты Комментарии
Последние комментарии
Посты Комментарии
Изменения
Посты Комментарии Изменения Черновики Избранное
Черновики (все)
Посты Комментарии Изменения Черновики Избранное
Избранное (всё)
Посты Комментарии Изменения Черновики Избранное
Лучшие блоги (все 127)
Элита (все 2421 из 196 городов)
welinux.ru