Как видите, мы получили сообщение об ошибке. Поэтому стоит всегда размещать ваши функции в начале кода или, по крайней мере, непосредственно перед вызовом функции.
Еще один пример использования функции:
#!/bin/bash
# admin.sh – инструмент для администратора
# функция new_user () создает новую учетную запись пользователя
new_user(){
echo "Подготовка к созданию новых пользователей ..."
sleep 2
# запускаем программу adduser adduser
}
echo "1. Добавить пользователя"
echo "2. Выход"
echo "Укажите, что вы хотите сделать:"
read choice
case $choice in
1) new_user # вызов функции new_user()
;;
*) exit
;;
esac
Для того чтобы приведенный скрипт работал правильно, вам необходимо запустить его из-под пользователя root, т. к. иначе программа adduser не сможет создать новых пользователей. Надеюсь, этот пример (хоть он и краток) показывает положительный эффект от использования функций.
Перехват сигналов
Вы можете использовать встроенную в bash программу trap для перехвата сигналов в своих программах. Это хороший способ изящно завершать работу программы. Например, если пользователь, когда ваша программа работает, нажмет CTRL-C — программе будет отправлен сигнал interrupt(SIGINT), который завершит ее. Функция trap позволит вам перехватить этот сигнал, что даст возможность либо продолжить выполнение программы, либо сообщить пользователю, что программа завершает работу. Синтаксис этой команды такой:
trap action signal
Здесь: action — то, что вы хотите делать, когда сигнал получен; signal — сигнал, на который стоит реагировать.
Список сигналов можно посмотреть с помощью команды trap -l.
При указании сигналов в своих скриптах можно опустить первые три буквы названия сигнала, т. е. SIG. Например, сигнал прерывания это — SIGINT. В вашем скрипте, в качестве его имени, можно указать просто INT. Вы также можете использовать номер сигнала, указанный рядом с его именем. Например, числовое значение сигнала SIGINT — 2. Попробуйте написать и запустить приведенный ниже пример:
#!/bin/bash
# использование команды trap
# перехватываем нажатие CTRL-C и запускаем функцию sorry()
trap sorry INT
# функция sorry() печатает сообщение
sorry(){
echo "Извини меня, Дэйв. Я не могу этого сделать"
sleep 3
}
# обратный отсчет от 10 до 1:
echo "Подготовка к уничтожению системы"
for i in 10 9 8 7 6 5 4 3 2 1; do
echo "Осталось $i секунд до уничтожения..."
sleep 1
done
echo "Запуск программы уничтожения!"
Наберите и запустите приведенный пример. Когда программа будет работать и вести обратный отсчет, нажмите CTRL-C. Это действие отправит программе сигнал прерывания — SIGINT. Тем не менее сигнал будет перехвачен командой trap, которая, в свою очередь, выполнит функцию sorry(). Вы можете заставить trap игнорировать сигнал, указав символ кавычек вместо указания действия. Также вы можете отключить ловушку с помощью тире: "-". Например:
# запускать функцию sorry(), если получен сигнал SIGINT
trap sorry INT
# отключение ловушки
trap - INT
# ничего не делать при получении сигнала
SIGINT trap " INT
Если вы отключаете ловушку, программа работает как обычно — при получении сигнала прерывается ее исполнение и она завершает работу. Когда вы говорите trap ничего не делать при получении сигнала — она делает именно это. Ничего. Программа будет продолжать работать, игнорируя сигнал.
Логические И и ИЛИ
Вы уже видели, что такое управляющие структуры и как их использовать. Для решения тех же задач есть еще два способа. Это логическое И — "&&" и логическое "ИЛИ" — « || ». Логическое И используется следующим образом:
выражение_1&&выражение_2
Сначала выполняется выражение, стоящее слева, если оно истинно, выполняется выражение, стоящее справа. Если выражение_1 возвращает ЛОЖЬ, то выражение_2 не будет выполнено. Если оба выражения возвращают ИСТИНУ, выполняется следующий набор команд. Если какое-либо из выражений не истинно, приведенное выражение считает ложным в целом. Другими словами, все работает так:
если выражение_1 истинно И выражение_2 истинно, тогда выполнять…[15]
Пример использования:
#!/bin/bash
x=5
y=10
if [ "$x" -eq 5 ] && [ "$y" -eq 10 ]; then
echo "Оба условия верны"
else
echo "Условия не верны"
fi
Здесь мы находим, что переменные х и у содержат именно те значения, которые мы проверяем, поэтому проверяемые условия верны. Если вы измените значение с х = 5 на х = 12, а затем снова запустите программу, она выдаст фразу «Условия не верны».
Логическое ИЛИ используется аналогичным образом. Разница лишь в том, что оно проверяет ошибочность выражения слева. Если это так — оно начинает выполнять следующий оператор:
выражение_1||выражение_2
Данное выражение в псевдокоде выглядит так:
если выражение_1 истинно ИЛИ выражение_2 истинно, выполняем …
Таким образом, любой последующий код будет выполняться, если хотя бы одно из выражений истинно:
#!/bin/bash
x=3
y=2
if [ "$x" -eq 5 ] || [ "$y" -eq 2 ]; then
echo "Одно из условий истинно"
else
echo "Ни одно из условий не является истинным"
fi
Здесь вы видите, что только одно из выражений истинно. Попробуйте изменить значение у и повторно запустите программу. Вы увидите сообщение, что ни одно из выражений не является истинным.
Аналогичная реализация условия с помощью оператора if будет большего размера, чем вариант с использованием логического И и ИЛИ, поскольку потребует дополнительного вложенного if. Ниже приведен код, реализующий тот же функционал, но с использованием оператора if:
#!/bin/bash
x=5
y=10
if [ "$x" -eq 5 ]; then
if [ "$y" -eq 10 ]; then
echo "Оба условия верны"
else
echo "Оба условия неверны"
fi
fi
Приведенный код менее нагляден для чтения и требует для своего написания больших усилий. Но у вас остается возможность для избавления себя от всех этих трудностей путем использования операторов логических И и ИЛИ.
Использование аргументов
Возможно, вы уже заметили, что большинство программ в Linux не интерактивны. Вы должны указать им какие-то параметры, в противном случае вы получите сообщение со списком возможных аргументов. Возьмем, к примеру, команду more. Если вы не укажете имя файла, она выдаст краткую справку по использованию программы. Ну и конечно же возможно сделать так, чтобы ваши скрипты также могли принимать аргументы. Для этого вам нужно знать что такое переменная вида $#. В ней содержится общее количество аргументов, переданных программе. Например, если вы запустите программу foo следующим образом:
15
При работе с булевыми переменными ИСТИНА и ЛОЖЬ (True и False), bash ведет себя отлично от других языков программирования. В других языках 0 соответствует False (Ложь), а 1 — True (Истина). В bash все наоборот. Связано это с такой вещью, как коды завершения программ (см. ниже).