Умовні оператори
Даний топік є четвертим топиком циклу «Мова командного інтерпретатора bash». Він буде розповідати про такі керуючих структурах мови, як умовні оператори. Але перед тим, як перейти до їх опису, необхідно зупинитися на деяких нюансах, які зроблять розгляд нижчевикладене матеріалу більш зрозумілим.
По-перше, розберемо, що таке список команд. Список команд - це одиночна команда, конвеєр або послідовність команд / конвеєрів, розділених одним з таких операторів: ";", "&&", "||", завершена крапкою з комою. ; - Оператор послідовного виконання кількох команд. Кожна наступна команда починає виконуватися тільки після завершення попередньої (неважливо, успішного чи ні); & & - Оператор виконання команди тільки після успішного виконання попередньої; | | - Оператор виконання команди тільки після помилкового виконання попередньої. Кодом успішного завершення є 0, а помилкового - не нуль (залежить від типу помилки). Не потрібно плутати зі звичайними мовами програмування, коли 1 є аналогом true, а 0 - false. Тепер можна приступити до безпосереднього розгляду умовних операторів.
Оператор варіантів case
Загальний синтаксис оператора case:
case значення in
шаблон1) список1;; шаблон2 | шаблон3) список2;; esac
Логічна послідовність виконання оператора case: а) шукається перший шаблон, що співпадає із значенням; б) якщо він знайдений, виконується відповідний йому список команд, завершений ";;"; в) управління передається операторам, наступним за конструкцією case. Шаблон і список розділяються символом ")". Одному списку команд може відповідати кілька умов, тоді їх потрібно розділяти символом "|". У шаблонах можна використовувати символи "*", "?", "[]", Про які було розказано в другому топіку циклу. З їх допомогою можна реалізувати інструкцію, діючу як default в операторі switch таких мов, як C, PHP. Наведу приклад використання case:
echo-n "[Універсальний просмоторщик] Вкажіть ім'я файлу:"; read File case "$ File" in
- . Jpg | *. gif | *. png)
eog $ File
- . Pdf) evince $ File;;
- . Txt) less $ File;;
- . Html) firefox $ File;;
/ Dev / *) echo "Ну це страшні файли." ;;
- )
echo "Ну добре, добре - не такий вже і універсальний." echo "Цей тип файлів мені не знайомий. Не знаю, чим його переглянути."
esac
Ще один приклад використання конструкції case:
echo "Помилка. Кому відправити повідомлення?" echo "Начальнику: b" echo "Колегам: c" echo "Нікому: any key" read answer case $ answer in
b | B) mail-s "error log" boss <error.log;; c | C) mail-s "Help! error log"-c denis nick <error.log;; *) Echo "error"; exit;;
esac
Умовний оператор if
Загальний синтаксис оператора if:
if список1 then
список2 [Elif спісок3 then спісок4] [Else спісок5] fi
Квадратні дужки тут вказують на необов'язкові конструкції. Логічна послідовність виконання оператора case: а) виконується список1; б) якщо він виконаний без помилок, виконується список2. В іншому випадку виконується спісок3, і якщо він завершується без помилок - спісок4. Якщо ж і спісок3 повертає код помилки, виконується спісок5; в) управління передається операторам, наступним за конструкцією if. Наведу приклад використання if:
if grep-q Bash file then echo "Файл містить, як мінімум, одне слово Bash." fi
Коли if і then розташовуються в одному рядку, то конструкції if і then повинні завершуватися крапкою з комою. Наприклад:
$ If [$? -Ne 0]; then echo "Error"; fi
Тепер, знаючи про можливість розташовувати if і then в одному рядку, перепишемо вищевказаний приклад:
if grep-q Bash file; then echo "Файл містить слово Bash." fi
Оператор test і умовні вирази
У наведеному вище прикладі замість аналізу коду завершення використана перевірка умови. Дві форми такої перевірки еквівалентні: вбудована команда test і [умова]. Наприклад, для перевірки існування файлу потрібно написати:
test-e <файл>
або
[-E <файл>]
Якщо використовуються квадратні дужки, вони обов'язково повинні бути відокремлені один від одного пробілом, тому що "[" - це назва команди, а "]" - це обов'язковий останній аргумент її завершення. У разі успішної перевірки умови, повертається 0, а в разі помилковості - код помилки 1. Команда test може перевіряти рядок на порожнечу. Непорожній рядок призводить до коду завершення 0. Порожня, відповідно - 1. Наприклад:
$ Test $ USER; echo $? 0
Конструкція "[[]]" більш універсальна, в порівнянні з "[]". Цей розширений варіант команди test. Всередині цієї конструкції не проводиться жодної додаткової інтерпретації імен файлів і не проводиться розбиття аргументів на окремі слова, але допускається підстановка параметрів і команд. Наприклад:
file = / etc / passwd if -e $ file then
echo "Файл паролів знайдено."
fi
Конструкція "[[]]" більш краща, ніж "[]", оскільки допоможе уникнути деяких логічних помилок. Наприклад, оператори "&&", "||", "<" і ">" всередині "[[]]" цілком припустимі, в той час як всередині "[]" породжують повідомлення про помилки. Конструкція "(())" дозволяє виробляти обчислення арифметичних виразів всередині неї. Якщо результатом обчислень є нуль, то повертається код помилки. Ненульовий результат обчислень дає код повернення 0. Тобто повна протилежність інструкцій test і "[]", що обговорювалося вище. Оператор if дозволяє припускати наявність вкладених перевірок:
if echo "Наступний * if * знаходиться всередині першого * if *."
if $ comparison = "integer" then ((a <b)) else [[$ A <$ b]] fi
then
echo '$ a менше $ b'
fi
Умовні вирази можна комбінувати за допомогою звичайних логічних операцій: ! <Вираз> - заперечення; <Вираз1>-a <вираз2> - логічне І; <Вираз1>-o <вираз2> - логічне АБО.
Елементарні умовні вирази для файлів: -E - файл існує; -F - звичайний файл (не каталог і не файл пристрою); -S - ненульовий розмір файлу; -D - файл є каталогом; -B - файл є блоковим пристроєм (floppy, cdrom і т.п.); -C - файл є символьним пристроєм (клавіатура, модем, звукова карта і т.п.); -P - файл є каналом; -H - файл є символічною посиланням; -L - файл є символічною посиланням; -S - файл є сокетом; -T - файл пов'язаний з термінальним пристроєм; -R - файл доступний для читання (користувачеві, що запустила сценарій); -W - файл доступний для запису (користувачеві, що запустила сценарій); -X - файл доступний для виконання (користувачеві, що запустила сценарій); -G - (sgid) прапор для файлу або каталогу встановлений; -U - (suid) прапор для файлу встановлений; -K - прапор sticky bit встановлений; -O - ви є власником файла; -G - ви належите до тієї ж групи, що й файл; -N - файл був модифікований з моменту останнього читання; файл1-nt файл2 - файл1 новіший, ніж файл2; файл1-ot файл2 - файл1 старіший, ніж файл2; файл1-ef файл2 - файл1 і файл2 є «жорсткими» посиланнями на один і той же файл.
Елементарні умовні вираз для порівняння рядків: -Z рядок - довжина рядка дорівнює 0; -N рядок - довжина рядка не дорівнює 0; рядок1 == рядок2 - рядки збігаються (аналог "="); рядок1! == рядок2 - рядки не збігаються (аналог "!="); рядок1 <рядок2 - рядок1 передує строке2 в лексикографічному порядку; рядок1> рядок2 - рядок1 слід за строкой2 в лексикографічному порядку. Арифметичне умовний вираз має формат: аргумент1 операція аргумент2, де аргументами є цілі числа, і припустимі наступні операції: -Eq - рівно; -Ne - не одно; -Lt - менше; -Le - менше або дорівнює; -Gt - більше; -Ge - більше або дорівнює; <- Менше (всередині подвійних круглих дужок); <= - Менше або дорівнює (всередині подвійних круглих дужок); > - Більше (всередині подвійних круглих дужок); > = - Більше або дорівнює (всередині подвійних круглих дужок).
Перепишемо попередній приклад з використанням оператора if:
echo "Помилка. Кому відправити повідомлення?" echo "Начальнику: b" echo "Колегам: c" echo "Нікому: any key" read answer if ["$ answer" == "b"-o "$ answer" == "B"]; then
mail-s "error log" boss <error.log;
elif ["$ answer" == "c"-o "$ answer" == "C"]; then
mail-s "Help! error log"-c denis nick <error.log;
else echo "error"; exit; fi