Привіт усім! В будь-якій мові програмування не обійтися без операторів вибірки. Bash не виключення і в даній статті ми розглянемо два оператори вибору і спеціальні умови тестування, які є корисними при роботі з файловою системою.

Оператори вибору

Оператор if

Загальний синтаксис оператора if наступний:
if iflist; 
then 
  thenlist; 
[ elif eilist; then eithenlist; ]
[ else elist; ] 
fi
У квадратних дужках вказані необов'язкові елементи. Якщо список команд “iflist”, вказані після оператора if, завершився з статусом нуль, в такому разі виконаються команди, які вказані у списку “then-list”. В іншому випадку, коли список команд “iflist” завершився з не нульовим статусом — виконується кожен наступний список команд “eilist”, які вказані після зарезервованого слова elif, якщо такі присутні. Якщо будь-який список команд “eilist” завершиться з нульовим статусом — виконання оператора завершується. В іншому випадку виконується список команд після ключового слова else, якщо такий блок команд присутній. Статус оператора, являється статусом завершення останньої виконаної команди, або нуль, якщо не виконалася жодна умова.

Оператор case

Команда case (в інших мовах програмування switch) має наступний синтаксис (квадратні дужки вказують на необов'язковість елемента):
case word in 
[ [(] pattern [ | pattern ] ) 
	list ;; ] 
esac
Спочатку виконання команди розраховується значення виразу “word”, після чого, отримане значення по-порядку співставляється з вказаними шаблонами. Якщо увімкнена опція nocasematch, кожне співставлення виконується без урахування регістру символів. Якщо виникло успішне співставлення значення з шаблоном, відповідний список команд “list” запускається на виконання. Якщо використаний оператор ;; - виконання команди case завершується. Використовуючи ;& на місці оператора ;; викликає продовження виконання команди по відношенню до наступних вказаних шаблонів-варіантів. Використання оператора ;;& на місці оператора ;; змушує оболонку тестувати наступні шаблони і виконувати їхні підпорядковані команди при успішному співставлені. Статус завершення являється нульовим, якщо жоден з шаблонів не був співставлений з значенням “word”. У протилежному випадку статус завершення оператора являється статус виходу останньої виконаної команди.

Спеціальні вирази умов

В командному інтерпретаторі Bash існують спеціальні команди, які дозволяють перевіряти особливі умови в операторах вибірки. Вирази умов можуть бути використаними всередині подвійних дужок “[[]]“, вбудованих командах test і “[]” для перевірки файлових атрибутів і виконання математичних порівнянь і порівнянь з рядками символів. Вирази формуються з наступних унарних і бінарних операторів. Якщо не вказано інше, дані оператори виконують дії над самими файлами, а не над символічними посиланнями файлової системи. Дані команди можуть бути наступними:
  • -a file — повертає true, якщо файл file існує;
  • -b file — повертає true, якщо файл file існує і являється спеціальним блоковим файлом;
  • -с file — повертає true, якщо файл file існує і являється спеціальним символьним файлом;
  • -d file — повертає true, якщо файл file існує і являється директорією;
  • -e file — повертає true якщо файл file існує;
  • -f file — повертає true, якщо файл file існує і являється звичайним файлом;
  • -g file — повертає true, якщо файл file існує і і має встановлений біт set-group-id;
  • -h file — повертає true, якщо файл file існує і являється символічним посиланням;
  • -k file — повертає true, якщо файл fike існує і має встановлений “липучий” біт;
  • -p file — повертає true, якщо файл file існує і являється FIFO-файлом;
  • -r file — повертає true, якщо файл file існує і доступний для читання;
  • -s file — повертає true, якщо файл file існує і має розмір відмінний від нуля;
  • -t fd — повертає true, якщо файловий дескриптор fd являється відкритим і відноситься до терміналу;
  • -u file — повертає true, якщо файл file існує і має встановлений біт set-user-id;
  • -w file — повертає true, якщо файл file існує і доступний для запису;
  • -x file — повертає true, якщо файл file існує і доступний для виконання;
  • -O file — повертає true, якщо файл file існує і поточний користувач являється його власником;
  • -G file — повертає true, якщо файл file існує і його група власників збігається з групою поточного користувача.
  • -L file — повертає true, якщо файл file існує і являється символічним посиланням.
  • -S file — повертає true, якщо файл file існує і являється сокетом;
  • -N file — повертає true, якщо файл file існує і являється модифікованим після попереднього виконання операції зчитування;
  • file1 -nt file2 — повертає true, якщо файл file1 являється новішим ніж файл file2 (по відношенню до дати модифікації), або файл file1 існує, а файл file2 ні;
  • file1 -ot file2 — повертає true, якщо файл file1 є старішим ніж файл file2, або якщо файл file2 існує а файл file1 ні;
  • file1 -ef file2 — повертає true, якщо файл file1 і file2 відносяться до одного жорсткого диску і розділу.
  • -o optname — повертає true, якщо увімкнутий параметр “optname” командного рядка;
  • -z string — поертає true, якщо рядок символів string має нульову довжину;
  • -n string (або просто string) — повертає true, якщо рядок символів string має довжину відмінну від нуля;
  • string1 == string2 — повертає true, якщо рядки символів ідентичні (можна використовувати оператор “=” для жорсткої відповідності стандарту POSIX);
  • string1 != string2 — повертає true, якщо вказані рядки символів не ідентичні;
  • string1 < string2 — повертає true, якщо рядок символів string1 стоїть перед string2 в лексикографічному сортуванні поточної локалі;
  • string1 > string2 — повертає true, якщо рядок символів string1 стоїть після string2 в лексикографічному сортуванні поточної локалі;
  • arg1 ОПЕРАТОР arg2 — ОПЕРАТОР являється одним з -eq, -ne. -lt, -le, -gt або -ge. Дані бінарні арифметичні оператори повертають true, якщо arg1 являється еквівалентним, не еквівалентним, меншим, меншим або еквівалентним, більшим, більшим або еквівалентним відносно arg2, відповідно. Arg1 або arg2 можуть бути негативними або позитивними цілими числами.

Приклади

Приклад по оператору if можна взяти з розділу прикладів статті “Bash-скриптинг: шаблони командного рядка”:
#!/bin/bash

# створюємо змінну для використання з шаблоном
str="this script is from kytok.org.ua"
pattern='[[:alpha:]]*kytok.org.ua'

# використовуємо шаблон з класом до рядка символів
if [[ $str = $pattern ]]
then
  echo "рядок '$str' співпадає з шаблоном '$pattern'"
else
  echo "рядок '$str' не співпадає з шаблоном '$pattern'"
fi

# змінюємо значення змінної str
str="1 script is from kytok.org.ua"
pattern='[[.one.]]*'

# використовуємо POSIX-ім'я символу в шаблоні
if [[ $str = $pattern ]]
then
  echo "рядок '$str' співпадає з шаблоном '$pattern'"
else
  echo "рядок '$str' не співпадає з шаблоном '$pattern'"
fi

# неподібний шаблон
if [[ $str = *[[.two.]]* ]]
then
  echo "рядок '$str' співпадає з шаблоном '*[[.two.]]*'"
else
  echo "рядок '$str' не співпадає з шаблоном '*[[.two.]]*'"
fi
Після виконання даного скрипта можна отримати наступний вивід в термінал: [caption id="attachment_866" align="aligncenter" width="1268"]Вивід простого скрипта, який показує використання шаблонів у командному інтерпретаторі Bash Вивід простого скрипта, який показує використання шаблонів у командному інтерпретаторі Bash[/caption] Приклад використання команди case:
#!/bin/bash

#вгадуємо тип файлу по вказаній назві
case $1 in
  *.gz | *.tar | *.bz2 | *.zip | *.7z | *.rar)
    echo "файл архіву" ;;
  *.sh)
    echo "файл Bash-скрипта" ;;
  *.txt | *.doc | *.docx | *.odt)
    echo "текстовий документ" ;;
  *.html | *.xhtml | *.php | *.css | *.js)
    echo "файл Web-сторінки" ;;
  *.jpg | *.jpeg | *.png | *.tiff | *.gif | *.bmp)
    echo "файл зображення" ;;
  *.mov | *.mp4 | *.3gp | *.avi | *.mpeg)
    echo "відеофайл" ;;
  *)
    echo "невідомий тип файлу" ;;
esac
Даний простий Bash скрипт намагається “вгадати” формат файлу по назві самого файлу, яку користувач передає в якості першого параметра скрипту. Вивід програми може бути наступним (файл case_sample.sh): [caption id="attachment_877" align="aligncenter" width="512"]Вивід простого скрипта з використанням оператора case Вивід простого скрипта з використанням оператора case[/caption] Розглянемо приклад використання спеціальних умов Bash.
#!/bin/bash

# перевіряємо чи існує файл
# якщо ні - вихід з скрипта
if [[ ! -e $1 ]]
then
 echo "Даного файлу не існує"
 exit 0
fi

# дана змінна буде містити повідомлення для користувача
msg="Файл '$1' існує і:\n"

# тестуємо переданий файл на відповідність умовам,
# які нас цікавлять
if [[ -d $1 ]] 
then 
  msg=$msg"\tявдяється директорією\n"
fi

if [[ -f $1 ]]
then
 msg=$msg"\tявляється звичайним файлом\n"
fi

if [[ -h $1 ]] 
then
  msg=$msg"\tявляється символічним посиланням\n"
fi

if [[ -s $1 ]] 
then
  msg=$msg"\tне пустий файл\n"
fi

if [[ -x $1 ]] 
then
  msg=$msg"\tдоступний для виконання\n"
fi

if [[ -O $1 ]] 
then
  msg=$msg"\tпоточний користувач являється власником файлу\n"
fi

# вивід на екран накопиченої інформації про файл
echo -e "$msg"
Даний скрипт тестує файл, переданий в якості першого параметра скрипта, на певні атрибути, і після чого виводить отриману статистику на екран. Вивід даного скрипта може бути наступний (скрипт розміщений у файлі conditional__expr.sh): [caption id="attachment_878" align="aligncenter" width="792"]Вивід простого скриптаЮ який демонструє використання оператора if і спеціальних умов Bash Вивід простого скриптаЮ який демонструє використання оператора if і спеціальних умов Bash[/caption]