Після засвоєння даного розділу ви зможете:

  • вживати цикли for, while та until і вирішувати, котрий цикл краще вживати в даній ситуації
  • використовувати вбудовані команди Bash brake та continue
  • писати сценарії з службовим словом select
  • писати сценарії, що приймають різну кількість аргументів

Цикл for

Як воно працює

Конструкція for – одна з трьох циклічних конструкцій bash. Вона дозволяє визначати перелік значень, для кожного із котрих виконається ряд команд.

Синтаксис цієї конструкції такий:

for ІМ’Я_ЗМІННОЇ [in СПИСОК]; do КОМАНДИ; done

Якщо частина [in СПИСОК] опущена, вона замінюється змінною $@ і цикл виконує КОМАНДИ один раз для кожного визначеного позиційного параметра (див параграфи 1.2.5 та 7.2.1.2).

Цикл повертає стан останньої виконаної команди. Якщо не виконувалась жодна команда тому, що при розкриванні [in СПИСОК] не було отримано яких-небудь елементів, цикл повертає 0.

ІМ’ЯЗМІННОЇ може бути будь-яким іменем; найчастіше вживається і. СПИСОК може бути будь-яким переліком слів, ланцюжків чи чисел, що можуть бути як задані явно, так і згенеровані будь-якою командою. КОМАНДИ для виконання можуть бути будь-якими командами операційної системи, сценаріями, зовнішніми командами чи конструкціями оболонки. Під час виконання першого проходу в циклі змінній ІМ’ЯЗМІННОЇ присвоюється перше значення з переліку СПИСОК; під час другого проходу – друге значення і так далі. Цикл закінчується, коли у переліку СПИСОК більше не залишиться значень.

Приклади

Вживання підстановки команд для визначення елементів списку

Перший приклад демонструє вживання команди for для створення резервних копій кожного .xml файлу. Після виклику команди з вашими статтями можна безпечно розпочинати роботу.

[carol@octarine ~/articles] ls *.xml
file1.xml  file2.xml  file3.xml

[carol@octarine ~/articles] ls *.xml > list

[carol@octarine ~/articles] for i in `cat list`; do cp "$i" "$i".bak ; done

[carol@octarine ~/articles] ls *.xml*
file1.xml  file1.xml.bak  file2.xml  file2.xml.bak  file3.xml  file3.xml.bak

Ця команда виводить список простих текстових файлів та, можливо, сценаріїв, у каталозі /sbin:

for i in `ls /sbin`; do file /sbin/$i | grep ASCII; done

Вживання вмісту змінної для визначення елементів списку

Нижче наведено сценарій для конвертування файлів HTML, створених за спеціальною схемою, у файли PHP. Конвертування відбувається вилученням перших 25 та останнього 21 рядка та заміни вилучених рядків тегами PHP, що містять заголовок та завершення файлів:

[carol@octarine ~/html] cat html2php.sh
#!/bin/bash
# Специфічний сценарій для перетворення моїх html в php
LIST="$(ls *.html)"
for i in "$LIST"; do
    NEWNAME=$(ls "$i" | sed -e 's/html/php/')
    cat beginfile > "$NEWNAME"
    cat "$i" | sed -e '1,25d' | tac | sed -e '1,21d'| tac >> "$NEWNAME"
    cat endfile >> "$NEWNAME"
done

Оскільки ми не знаємо кількості рядків у файлах, то й не маємо можливості дізнатись, коли починати видаляти рядки у кінці файлу. Тому ми використаємо команду tac, котра змінює порядок рядків у файлі.

Цикл while

Що це таке?

Конструкція while дозволяє повторно виконувати список команд до тих пір, поки успішно виконується команда, що контролює цикл (її стан завершення рівних нулю). Її синтаксис наступний:

while КОНТРОЛЮЮЧА_КОМАНДА; do ПОСЛІДОВНІСТЬ_КОМАНД; done

КОНТРОЛЮЮЧАКОМАНДА може бути будь-якою командою, що може повертати успішний чи неуспішний стан завершення. ПОСЛІДОВНІСТЬКОМАНД може бути будь-якою командою, сценарієм чи конструкцією оболонки.

Як тільки КОНТРОЛЮЮЧА_КОМАНДА завершилась невдало, цикл переривається. У сценарії виконуються команди, що йдуть слідом за командою done.

Цикл повертає стан завершення останньої команди у ПОСЛІДОВНОСТІКОМАНД, або ж нуль, якщо ПОСЛІДОВНІСТЬКОМАНД не виконувалась.

Приклади

Простий приклад вживання while

Ось простенький приклад для нетерплячих:

#!/bin/bash

# Цей сценарій відкриває 4 вікна терміналів

i="0"

while [ $i -lt 4 ]
do
xterm &
i=$[$i+1]
done

Вкладені цикли while

Наведений приклад був написаний щоб переписати фото, зроблені веб-камерою у каталог web. Кожних 5 хвилин робиться нове фото. Щогодини створюється новий каталог, що містить фото, отримані в даній годині. Щодня створюється новий каталог, що містить 24 підкаталоги. Сценарій запускається у фоновому режимі.

#!/bin/bash

# Цей сценарій копіює файли з мого домашнього каталога у каталог веб-сервера 
# (за допомогою scp та ключів SSH для віддалених каталогів)
# Щогодини створюється новий каталог

PICSDIR=/home/carol/pics
WEBDIR=/var/www/carol/webcam

while true; do 
    DATE=`date +%Y%m%d`
    HOUR=`date +%H`
    mkdir $WEBDIR/"$DATE"

    while [ $HOUR -ne "00" ]; do 
        DESTDIR=$WEBDIR/"$DATE"/"$HOUR"
        mkdir "$DESTDIR"
        mv $PICDIR/*.jpg "$DESTDIR"/
        sleep 3600
        HOUR=`date +%H`
    done
done

Зверніть увагу на вживання оператора true. Це означає: виконувати до тих пір, поки ми не перервемо насильно (за допомогою kill чи Ctrl+C).

Цей маленький сценарій буде використовуватись для перевірки; він генеруватиме файли:

#!/bin/bash

# Сценарій генерує файли кожних 5 хвилин

while true; do
touch pic-`date +%s`.jpg
sleep 300
done

Зверніть увагу на вживання команди date для генерування імен як файлів, так і каталогів. Зверніться до сторінки довідки команди date за детальнішою інформацією.

Увага: Використовуйте системні інструменти!

Попередній сценарій написаний з демонстраційною метою. Регулярні перевірки можуть легко виконуватись за допомогою демона cron. Не забудьте лише перенаправити стандартний вивід та помилки для сценаріїв, що виконуватимуться з файлу crontab.

Використання вводу з клавіатури для контролю циклу while

Цей сценарій може бути перерваний, якщо користувач натисне Ctrl+C:

#!/bin/bash

# Цей сценарій імітує мудрість

FORTUNE=/usr/games/fortune

while true; do
echo "По якій темі ви потребуєте поради?"
cat << topics
politics
startrek
kernelnewbies
sports
bofh-excuses
magic
love
literature
drugs
education
topics

echo
echo -n "Введіть ваш вибір: "
read topic
echo
echo "Порада на тему $topic: "
echo
$FORTUNE $topic
echo

done

Для представлення користувачеві списку вибору використовується документна вставка. Знову ж таки, оператор true повторює команди з ПОСЛІДОВНОСТІ_КОМАНД знову й знову.

Розрахунок середнього значення

Цей сценарій розраховує середнє значення з вводу користувача, котрий перевіряється перед обробкою: якщо ввід не потрапляє у допустимий діапазон, видається відповідне повідомлення. Якщо натиснуто клавішу q, цикл завершується:

#!/bin/bash

# Розрахунок середнього значення з переліку чисел

SCORE="0"
AVERAGE="0"
SUM="0"
NUM="0"

while true; do

  echo -n "Введіть ваші очки [0-100%] ('q' щоб вийти): "; read SCORE;

  if (("$SCORE" < "0"))  || (("$SCORE" > "100")); then
    echo "Будь серйозним. Нуж бо, спробуй ще раз:"
  elif [ "$SCORE" == "q" ]; then
    echo "Середнє значення: $AVERAGE%."
    break
  else
    SUM=$[$SUM + $SCORE]
    NUM=$[$NUM + 1]
    AVERAGE=$[$SUM / $NUM]
  fi

done

echo "Завершую."

Зверніть увагу, як екрануються змінні у останніх рядках щоб зробити арифметичні операції.

Цикл until

Що це таке?

Цикл until дуже подібний до while, єдина відмінність полягає в тому, що цикл завершується, якщо КОНТРОЛЮЮЧА_КОМАНДА завершується успішно. Поки вона завершується невдачею, цикл виконується. Синтаксис такий же самий, як і для while:

until КОНТРОЛЮЮЧА_КОМАНДА; do ПОСЛІДОВНІСТЬ_КОМАНД; done

Цикл повертає стан завершення останньої команди з ПОСЛІДОВНОСТІКОМАНД, або ж нуль, якщо команди не виконувались. КОНТРОЛЮЮЧАКОМАНДА, знову ж таки, може бути будь-якою командою, що повертає завершується успіхом чи невдачею, а ПОСЛІДОВНІСТЬ_КОМАНД може бути будь-якою UNIX-командою, сценарієм, чи конструкцією оболонки.

Приклад

Виправлений сценарій picturesort.sh з розділу 9.2.2.2 тепер перевіряє наявність вільного місця на диску. Якщо його немає, він витирає фото за попередній місяць:

#!/bin/bash

# Цей сценарій копіює файли з мого домашнього каталога у каталог веб-сервера 
# Щогодини створюється новий каталог
# Якщо фото займають надто багато місця, найстаріші видаляються.

while true; do 
    DISKFUL=$(df -h $WEBDIR | grep -v File | awk '{print $5 }' | cut -d "%" -f1 -)

    until [ $DISKFUL -ge "90" ]; do 

            DATE=`date +%Y%m%d`
            HOUR=`date +%H`
            mkdir $WEBDIR/"$DATE"

            while [ $HOUR -ne "00" ]; do
                    DESTDIR=$WEBDIR/"$DATE"/"$HOUR"
                    mkdir "$DESTDIR"
                    mv $PICDIR/*.jpg "$DESTDIR"/
                    sleep 3600
                    HOUR=`date +%H`
            done

    DISKFULL=$(df -h $WEBDIR | grep -v File | awk '{ print $5 }' | cut -d "%" -f1 -)
    done

    TOREMOVE=$(find $WEBDIR -type d -a -mtime +30)
    for i in $TOREMOVE; do
        rm -rf "$i";
    done

done

Зверніть увагу на ініціалізацію змінних HOUR та DISKFULL та використання опцій ls і date щоб отримати правильний вміст змінної TOREMOVE.

Перенаправлення вводу-виводу та цикли

Перенаправлення вводу

Замість контролювати цикл, перевіряючи результат виконання команди чи ввід користувача, ви можете зазначити файл з котрого читати ввід, що контролює цикл. В таких випадках контролюючою командою часто є read. Поки зчитані рядки потрапляють в цикл, виконання команд циклу продовжуватимуться. Як тільки вони закінчаться, виконання циклу перерветься. Оскільки цикл розглядається як одна структура (наприклад, while КОНТРОЛЮЮЧАКОМАНДА; do ПОСЛІДОВНІСТЬКОМАНД; done), перенаправлення можна ставити після оператора done, і воно прийме форму:

КОМАНДА < ФАЙЛ

Такий вид перенаправлення працює і з іншими циклами.

Перенаправлення виводу

В наведеному нижче прикладі вивід команди find вживається як ввід команди read, що контролює цикл while:

[carol@octarine ~/testdir] cat archiveoldstuff.sh
#!/bin/bash

# Цей сценарій створює підкаталог у поточному каталозі, у котрий
# переміщує застарілі файли
# Може викликатись за допомогою cron (якщо трішки переробити) щотижня 
# чи щомісяця.

ARCHIVENR=`date +%Y%m%d`
DESTDIR="$PWD/archive-$ARCHIVENR"

mkdir $DESTDIR

find $PWD -type f -a -mtime +5 | while read file
do
gzip "$file"; mv "$file".gz "$DESTDIR"
echo "$file заархівовано."
done

Файли стискаються перед переміщенням.

Break та continue

Вбудована команда break

Оператор break вживається для переривання нормального виконання циклу. Це робиться, якщо вам невідомо наперед, скільки разів виконається цикл, наприклад, якщо він залежить від вводу користувача.

Наведений нижче приклад демонструє цикл while, що може бути перерваний. Це злегка вдосконалена версія сценарію wisdom.sh з параграфу 9.2.2.3.^soggie

#!/bin/bash

# Цей сценарій імітує розумну поведінку.
# Тепер ви можете коректно завершити його.

FORTUNE=/usr/games/fortune

while true; do
echo " По якій темі ви потребуєте поради?"
echo "1.  politics"
echo "2.  startrek"
echo "3.  kernelnewbies"
echo "4.  sports"
echo "5.  bofh-excuses"
echo "6.  magic"
echo "7.  love"
echo "8.  literature"
echo "9.  drugs"
echo "10. education"
echo

echo -n "Введіть ваш вибір, або ж 0 щоб вийти: "
read choice
echo

case $choice in
     1)
     $FORTUNE politics
     ;;
     2)
     $FORTUNE startrek
     ;;
     3)
     $FORTUNE kernelnewbies
     ;;
     4)
     echo "Спорт – це втрата часу, енергії та грошей."
     echo "Повертайтесь до клавіатури."
     echo -e "\t\t\t\t -- \"Хвороба – моє друге ім’я\" Soggie."
     ;;
     5)
     $FORTUNE bofh-excuses
     ;;
     6)
     $FORTUNE magic
     ;;
     7)
     $FORTUNE love
     ;;
     8)
     $FORTUNE literature
     ;;
     9)
     $FORTUNE drugs
     ;;
     10)
     $FORTUNE education
     ;;
     0)
     echo "До зустрічі!"
     break
     ;;
     *)
     echo "Це невірний вибір. Спробуйте число від 1 до 10"
     ;;
esac  
done

Запам’ятайте, що break завершує цикл, а не сценарій. Це може бути показано, додавши команду echo в кінці сценарію. Вона буде виконана під час вводу, що заставить спрацювати оператор break (коли користувач введе „0”).

У вкладених циклах оператор break дозволяє вказувати, котрий цикл переривати. Зверніться до сторінок довідки info Bash за детальнішою інформацією.

Вбудована команда continue

Оператор continue починає нову ітерацію циклу, закриваючи поточну. У циклі for КОНТРОЛЮЮЧАЗМІННА приймає значення наступного елементу списку. У конструкціях while та until виконання продовжується з КОНТРОЛЮЮЧОЇКОМАНДИ на початку циклу.

Приклади

У наступному прикладі імена файлів переводяться у нижній регістр. Якщо перетворення не потрібне, оператор continue перезапускає виконання циклу. Ці команди не споживають багато системних ресурсів і хоча схожі проблеми можна вирішити за допомогою sed чи awk, проте такий вид конструкцій можна вживати, коли виконуються ресурсоємні задачі. У потрібні місця сценарію додано перевірки – для економії системних ресурсів.

[carol@octarine ~/test] cat tolower.sh
#!/bin/bash

# Цей сценарій перетворює всі імена файлів, що містять великі літери, у 
# імена, що складаються лише з малих літер.

LIST="$(ls)"

for name in "$LIST"; do

if <span class="createlink"><a href="/cgi-bin/ikiwiki.cgi?page=___34____36__name__34_____33____61_____42____91____91__%3Aupper%3A&amp;from=LDP%2FBash_beginners_guide%2Frepetitive_tasks&amp;do=create" rel="nofollow">?</a> &#34;&#36;name&#34; &#33;&#61; &#42;&#91;&#91;:upper:</span>* ]]; then
continue
fi

ORIG="$name"
NEW=`echo $name | tr 'A-Z' 'a-z'`

mv "$ORIG" "$NEW"
echo "Файл $ORIG перейменовано у $NEW"
done

Цей сценарій має як мінімум одну незручність: він перезаписує існуючі файли. Опцію Bash noclobber зручно вживати лише під час перенаправлення. Опція –b команди mv є більш безпечною, але її доцільно вживати лише під час випадкового перезаписування, як показано нижче:

[carol@octarine ~/test] rm *

[carol@octarine ~/test] touch test Test TEST

[carol@octarine ~/test] bash -x tolower.sh
++ ls
+ LIST=test
Test
TEST
+  <span class="createlink"><a href="/cgi-bin/ikiwiki.cgi?page=_test___33____61_____42____91____91__%3Aupper%3A&amp;from=LDP%2FBash_beginners_guide%2Frepetitive_tasks&amp;do=create" rel="nofollow">?</a> test &#33;&#61; &#42;&#91;&#91;:upper:</span>* ]] 
+ continue
+  <span class="createlink"><a href="/cgi-bin/ikiwiki.cgi?page=_Test___33____61_____42____91____91__%3Aupper%3A&amp;from=LDP%2FBash_beginners_guide%2Frepetitive_tasks&amp;do=create" rel="nofollow">?</a> Test &#33;&#61; &#42;&#91;&#91;:upper:</span>* ]] 
+ ORIG=Test
++ echo Test
++ tr A-Z a-z
+ NEW=test
+ mv -b Test test
+ echo 'Файл Test перейменовано в test'
Файл Test перейменовано в test
+  <span class="createlink"><a href="/cgi-bin/ikiwiki.cgi?page=_TEST___33____61_____42____91____91__%3Aupper%3A&amp;from=LDP%2FBash_beginners_guide%2Frepetitive_tasks&amp;do=create" rel="nofollow">?</a> TEST &#33;&#61; &#42;&#91;&#91;:upper:</span>* ]] 
+ ORIG=TEST
++ echo TEST
++ tr A-Z a-z
+ NEW=test
+ mv -b TEST test
+ echo ' Файл TEST перейменовано в test '
Файл TEST перейменовано в test

[carol@octarine ~/test] ls -a
./  ../  test  test~

tr є частиною пакунку textutils; вона дозволяє здійснювати будь-які перетворення символів.

Створення меню за допомогою вбудованої команди select

Вживання select^headings

Конструкція select дозволяє легко сформувати меню. Її синтаксис дуже подібний до циклу for:

select СЛОВО [in СПИСОК]; do ПОВТОРЮВАНІ_КОМАНДИ; done

СПИСОК розширюється, формуючи перелік елементів. Розширення друкується на стандартний вивід помилок; кожному елементові списку передує його порядковий номер. Якщо частина [in СПИСОК] відсутня, друкуються позиційні параметри, визначені в змінній $@. СПИСОК друкується лише один раз.

Після роздруку всіх елементів виводиться підказка PS3 і зчитується один рядок вводу. Якщо він складається з числа, що відноситься до одного з елементів списку, значенню змінної СЛОВО присвоюється значення відповідного елементу переліку. При введенні якогось іншого значення змінній присвоюється порожній ланцюжок. Якщо рядок вводу порожній, елементи списку та підказка PS3 друкуються знову. При зчитування символу EOF (кінець файлу) цикл завершується. Але оскільки більшість користувачів не знають комбінації клавіш, що позначає символ кінця файлу, значно зручніше одним із елементів поставити команду break.

Зчитаний рядок зберігається у змінній REPLY.

ПОВТОРЮВАНІ_КОМАНДИ виконуються після кожного вибору аж допоки не буде зчитане число, що представляє команду break. Це завершує цикл.

Приклади

Ось дуже простий сценарій, але, як бачите, він незручний у користуванні.

[carol@octarine testdir] cat private.sh
#!/bin/bash

echo "Цей сценарій робить особистими будь-які файли у поточному каталозі."
echo "Введіть номер файлу, який ви хочете захистити:"

select FILENAME in *;
do
     echo "Ви вибрали $FILENAME ($REPLY), відтепер він доступний лише вам."
     chmod go-rwx "$FILENAME"
done

[carol@octarine testdir] ./private.sh
Цей сценарій робить особистими будь-які файли у поточному каталозі.
Введіть номер файлу, який ви хочете захистити:
1) archive-20030129
2) bash
3) private.sh
#? 1
Ви вибрали archive-20030129 (1), відтепер він доступний лише вам.
#?

Установка підказки PS3 та додавання можливості коректного виходу робить його кращим:

#!/bin/bash

echo "Цей сценарій робить особистими будь-які файли у поточному каталозі."
echo "Введіть номер файлу, який ви хочете захистити:"

PS3="Ваш вибір: "
QUIT="ВИЙТИ З ПРОГРАМИ."
touch "$QUIT"

select FILENAME in *;
do
  case $FILENAME in
        "$QUIT")
          echo "Завершую."
          break
          ;;
        *)
          echo "Ви вибрали $FILENAME ($REPLY)"
          chmod go-rwx "$FILENAME"
          ;;
  esac
done
rm "$QUIT"

Підменю

Оскільки всередині команди select можна вживати будь-яку конструкцію, то це може бути ще одна команда select, що формуватиме підменю всередині основного меню. По замовчуванню змінна PS3 не змінюється у вкладених меню. Якщо ви хочете мати різні підказки на різних рівнях вкладеності меню, ви повинні задавати їх самостійно.

Вбудована команда shift

Що вона робить?

Команда shift приймає лише один аргумент, число. Всі позиційні параметри зміщуються ліворуч на задану кількість позицій N. Позиційні параметри від N+1 до $# перейменовуються у змінні від $1 до $# -N +1.

Скажімо, якщо у вас команда приймає 10 аргументів і N становить 4, тоді $4 стає $1, $5 – $2 і так далі, аж до $10, що стає $7. Оригінальні $1, $2 і $3 втрачаються. Якщо N не задане, воно приймається рівним 1. Стан завершення є нуль, поки N більше за $# чи менше за нуль; в інших випадках він не рівний нулю.

Приклади

Оператор shift як правило вживається тоді, коли ми не знаємо, скільки аргументів передано в наш сценарій, наприклад, якщо користувач може їх ввести стільки, скільки хоче. В таких випадках аргументи обробляються в циклі while з контролюючою командою (($#)). Ця умова є істинною, якщо кількість аргументів більша за нуль. Змінна $1 та оператор shift обробляють кожен наступний аргумент. Кількість аргументів зменшується з кожним викликом shift і кінець кінцем вони вичерпаються; тоді ж завершиться цикл їх обробки.

В наведеному прикладі сценарій cleanup.sh за допомогою оператора shift обробляє кожен файл, знайдений командою find:

 #!/bin/bash

 # Цей сценарій видаляє файли, до котрих не звертались більше, аніж 365 днів.

 USAGE="Вживання: $0 dir1 dir2 dir3 ... dirN"

 if [ "$#" == "0" ]; then
    echo "$USAGE"
    exit 1
 fi

 while (( "$#" )); do

 if <span class="createlink"><a href="/cgi-bin/ikiwiki.cgi?page=___34____36____40__ls___36__1__41____34_____61____61_____34____34___&amp;from=LDP%2FBash_beginners_guide%2Frepetitive_tasks&amp;do=create" rel="nofollow">?</a> &#34;&#36;&#40;ls &#36;1&#41;&#34; &#61;&#61; &#34;&#34; </span>; then 
    echo "Порожній каталог, немає що робити."
   else 
    find $1 -type f -a -atime +365 -exec rm -i {} \;
 fi

 shift

 done

Примітка: exec проти xargs

Наведена вище команда find може бути замінена наступною:

find опції | xargs [команди_що_оброблятимуть_знайдені_файли

Команда xargs отримує командний рядок з стандартного вводу. Вона має ту перевагу, що командний рядок заповнюється до тих пір, поки не буде досягнуто системного обмеження. Лише тоді команди будуть викликані на виконання; в нашому прикладі це є rm. Якщо є додаткові аргументи, буде використано новий командний рядок і так до тих пір, поки він не переповниться або поки будуть поступати нові аргументи. Те ж саме досягається, коли ми вживаємо зв’язку find -exec, але все ж використання команди xargs значно пришвидшить роботу ваших сценаріїв та зекономить ресурси системи.

У поданому прикладі ми змінимо сценарій з параграфу 8.2.2.4 так, щоб він приймав довільну кількість пакунків для встановлення:

#!/bin/bash
if [ $# -lt 1 ]; then
        echo "Вживання: $0 пакунок(и)"
        exit 1
fi
while (($#)); do
    yum install $1 << CONFIRM
    y
    CONFIRM
    shift
done

Підсумок

В цьому розділі ми обговорили, як повторювані команди можуть застосовуватись у циклах. Найуживаніші циклічні конструкції будуються за допомогою операторів for, while та until, або їх комбінаціями. Цикл for виконує завдання визначену кількість разів. Якщо ви не знаєте, скільки разів повинна виконатись команда, зверніться до while або until щоб визначити, коли цикл має завершитись.

Цикли можуть бути перервані чи продовжені за допомогою операторів break та continue. Файли можуть використовуватись як ввід для циклів за допомогою операторів перенаправлення; цикли можуть також зчитувати вивід команд, що об’єднані з ними у конвеєр.

Конструкція select використовується для генерування меню у діалогових сценаріях. Аналіз аргументів командного рядка може бути здійснений за допомогою оператора shift.

Вправи

Запам’ятайте: при написанні сценаріїв працюйте покроково і перевіряйте кожен крок замість шукати помилки у цілому сценарії.

  1. Напишіть сценарій, котрий би рекурсивно копіював файли з /etc щоб системний адміністратор міг їх безбоязно редагувати.
  2. Напишіть сценарій, що приймає лише один аргумент – назву каталогу. Якщо кількість аргументів більша або менша за одиницю, надрукуйте повідомлення про те, як правильно вживати сценарій. Якщо аргумент не каталог, виведіть відповідне повідомлення. Для заданого каталогу надрукуйте п’ять файлів, що були змінені останніми.
  3. Чи можете ви пояснити, чому так важливо помістити змінні у подвійні квадратні дужки у прикладі з параграфу 9.4.2?
  4. Напишіть сценарій, подібний до наведеного у параграфі 9.5.1, але з можливістю завершення після того, як користувач тричі виконає цикл.
  5. Подумайте про краще рішення, аніж move –b у сценарію з параграфу 9.5.3 щоб попередити перезапис існуючих файлів. Наприклад, перевіряйте, чи є вже такий файл. Не робіть непотрібної роботи!
  6. Перепишіть сценарій whichdaemon.sh з параграфу 7.2.4 так, щоб він:

  7. друкував список серверів, що мають перевірятись, наприклад Apache, SSH, NTP, сервер доменних назв (DNS), демон керування живленням та ін.

  8. для кожного зробленого користувачем вибору друкував якусь зрозумілу інформацію, наприклад назву веб-серверу, інформацію про трасування NTP і т.ін.
  9. давав користувачеві можливість вибрати інші сервери окрім запропонованих. В такому випадку як мінімум перевіряв, чи такий демон запущений.
  10. прогляньте сценарій з параграфу 9.2.2.4. Зверніть увагу, як обробляється ввід символів відмінних від q. Перепишіть сценарій таким чином щоб він виводив повідомлення, якщо введено якісь літери.

Хтось підкаже, що воно таке і як перекладається?