Моя цель: рассказать о популярном командном интерпретаторе Linux — bash: для чего он предназначен, как использовать переменные, передача параметров в сценарий, как делаются различные циклы и использование условных операторов. Будет интересно! К концу статьи вы будете писать собственные сценарии.
Почему bash?
bash — это наиболее часто используемая командная оболочка (командный интерпретатор) Linux. Основное предназначение bash — выполнение команд, введенных пользователем. Пользователь вводит команду, bash ищет программу, соответствующую команде, в каталогах, указанных в переменной окружения PATH . Если такая программа найдена, то bash запускает ее и передает ей введенные пользователем параметры. В противном случае выводится сообщение о невозможности выполнения команды.
Кроме bash существуют и другие оболочки — sh, csh, ksh, zsh и пр. Все командные оболочки, установленные в системе, прописаны в файле /etc/shells.
При запуске LInux оболочка bash выполняет сценарий .bashrc (невидимый файл), находящийся в домашнем каталоге пользователя. В этом файле можно указать команды, которые нужно выполнить сразу после входа пользователя в систему. Данный файл не обязателен и может отсутствовать.
В файле .bash_history (тоже находится в домашнем каталоге) хранится история команд, введенных пользователем. Так что вы можете просмотреть свои же команды, которые накануне вводили.
Автоматизация задач с помощью bash
Представим, что нам нужно выполнить резервное копирование всех важных файлов, для этого создать архивы каталогов /etc, /home и /usr. Понятно, что понадобятся три команды вида:
tar -cvjf имя_архива.tar.bz2 каталог
Допустим, затем записать все эти три файла на DVD с помощью любой программы для прожига DVD.
Если выполнять эту операцию раз в месяц (или хотя бы раз в неделю), то ничего страшного. Но представьте, что вам нужно делать это каждый день или даже несколько раз в день? Думаю, такая рутинная работа вам быстро надоест. А ведь можно написать сценарий, который сам будет создавать резервные копии и записывать их на DVD! Все, что вам нужно, — это вставить чистый DVD перед запуском сценария.
Можно пойти и иным путем. Написать сценарий, который будет делать резервные копии системных каталогов и записывать их на другой раздел жесткого диска. Ведь не секрет, что резервные копии делаются не только на случай сбоя системы, но и для защиты от некорректного изменения данных пользователем.
«Привет, мир!»
Хотелось бы поскорей своими руками написать свой первый сценарий, правда?.. :-) По традиции напишем сценарий, выводящий всем известную фразу: "Привет, мир!". Вся работа со сценариями выполняется обычно в консоли (или в терминале), но для редактирования сценариев вы можете использовать любимый графический редактор, я в Linux Mint использую xed.
Первый сценарий
#!/bin/bash
echo "Привет, мир!"
Первая строка нашего сценария — это указание, что он должен быть обработан программой /bin/bash. Обратите внимание — если между # и ! окажется пробел, то данная директива не сработает, поскольку будет воспринята как обычный комментарий. Комментарии начинаются, как мы знаем, с решетки:
# Комментарий
Вторая строка — это оператор echo , выводящий нашу строку. Сохраните сценарий под именем hello и введите команду:
$ chmod +x hello
Для запуска сценария введите команду:
./hello
На экране вы увидите строку:
Привет, мир!
Чтобы вводить для запуска сценария просто hello (без ./ ), сценарий нужно скопировать в каталог /usr/bin (точнее, в любой каталог, прописанный в переменной окружения PATH ):
# cp ./hello /usr/bin
Вот и готов наш первый сценарий!
Использование переменных в собственных сценариях
В любом серьезном сценарии вы не обойдетесь без использования переменных. Переменные можно объявлять в любом месте сценария, но до места их первого применения. Рекомендуется объявлять переменные в самом начале сценария, чтобы потом не искать, где вы объявили ту или иную переменную.
Для объявления переменной используется следующая конструкция:
переменная=значение
Пример объявления переменной:
ADDRESS=www.yandex.ru
echo $ADDRESS
Обратите внимание на следующие моменты:
- при объявлении переменной знак доллара не ставится, но он обязателен при использовании переменной;
- при объявлении переменной не должно быть пробелов до и после знака = .
Значение для переменной указывать вручную не обязательно — его можно прочитать с клавиатуры:
read ADDRESS
или со стандартного вывода программы:
ADDRESS=`hostname`
Чтение значения переменной с клавиатуры осуществляется с помощью инструкции read . При этом указывать символ доллара не нужно. Вторая команда устанавливает в качестве значения переменной ADDRESS вывод команды hostname .
В Linux часто используются переменные окружения. Это специальные переменные, содержащие служебные данные. Вот примеры некоторых часто используемых переменных окружения:
HOME — домашний каталог пользователя, который запустил сценарий;
RANDOM — случайное число в диапазоне от 0 до 32 767;
UID — ID пользователя, который запустил сценарий;
PWD — текущий каталог.
Для установки собственной переменной окружения используется команда export :
# присваиваем переменной значение
$ADDRESS=www.yandex.ru
# экспортируем переменную — делаем ее переменной окружения
# после этого переменная ADDRESS будет доступна в других сценариях
export $ADDRESS
Передача параметров сценарию
Очень часто сценариям нужно передавать различные параметры, например режим работы или имя файла/каталога. Для передачи параметров используются следующие специальные переменные:
$0 — содержит имя сценария;
$n — содержит значение параметра ( n — номер параметра);
$# — позволяет узнать количество параметров, которые были переданы.
Давайте рассмотрим небольшой пример обработки параметров сценария. Друзья, конструкцию case-esac мы еще не рассматривали, но общий принцип должен быть понятен.
Пример обработки параметров сценария
# сценарий должен вызываться так:
# имя_сценария параметр
# анализируем первый параметр
case "$1" in
start)
# действия при получении параметра start
echo "Запускаем сетевой сервис"
;;
stop)
# действия при получении параметра stop
echo "Останавливаем сетевой сервис"
;;
*)
# действия в остальных случаях
# выводим подсказку о том, как нужно использовать сценарий,
# и завершаем работу сценария
echo "Usage: $0 {start|stop }"
exit 1
;;
esac
Думаю, приведенных комментариев достаточно, поэтому подробно рассматривать работу сценария не будем.
Массивы и bash
Интерпретатор bash позволяет использовать массивы. Массивы объявляются подобно переменным. Вот пример объявления массива:
ARRAY[0]=1
ARRAY[1]=2
echo $ARRAY[0]
Циклы
Как и в любом языке программирования, в bash можно использовать циклы. Мы рассмотрим циклы for и while , хотя вообще в bash доступны также циклы until и select , но они применяются, на мой взгляд, редко.
Синтаксис цикла for выглядит так:
for переменная in список
do
команды
done
В цикле при каждой итерации переменной будет присвоен очередной элемент списка, над которым будут выполнены указанные команды. Чтобы было понятнее, рассмотрим небольшой пример:
for n in 1 2 3;
do
echo $n;
done
Обратите внимание — список значений и список команд должны заканчиваться точкой с запятой.
Как и следовало ожидать, наш сценарий выведет на экран следующее:
1
2
3
Синтаксис цикла while выглядит немного иначе:
while условие
do
команды
done
Цикл while выполняется до тех пор, пока истинно заданное условие. Подробно об условиях расскажу далее, а пока напишем аналог предыдущего цикла, т. е. нам нужно вывести 1, 2 и 3, но с помощью while, а не for:
n=1
while [ $n -lt 4 ]
do
echo "$n "
n=$(( $n+1 ));
done
Условные операторы
В bash доступны два условных оператора — if и case . Синтаксис оператора if следующий:
if условие_1 then
команды_1
elif условие_2 then
команды_2
...
elif условие_N then
команды_N
else
команды_N+1
fi
Оператор if в bash работает аналогично оператору if в других языках программирования. Если истинно первое условие, то выполняется первый список команд, иначе — проверяется второе условие и т. д. Количество блоков elif , понятно, не ограничено.
Самая ответственная задача — это правильно составить условие. Условия записываются в квадратных скобках. Вот пример записи условий:
# переменная N = 10
[ N==10 ]
# переменная N не равна 10
[ N!=10 ]
Операции сравнения указываются не с помощью привычных знаков > или <, а с помощью следующих выражений:
-lt — меньше;
-gt — больше;
-le — меньше или равно;
-ge — больше или равно;
-eq — равно (используется вместо ==).
Взято из языка Си. :-)
Применять данные выражения нужно следующим образом:
[ переменная выражение значение|переменная ]
Например:
# N меньше 10
[$N -lt 10 ]
# N меньше A
[ $N -lt $A ]
В квадратных скобках вы также можете задать выражения для проверки существования файла и каталога:
-e файл — условие истинно, если файл существует;
-d каталог — условие истинно, если каталог существует;
-x файл — условие истинно, если файл является исполнимым.
С оператором case мы уже немного знакомы, но сейчас рассмотрим его синтаксис подробнее:
case переменная in
значение_1) команды_1 ;;
...
значение_N) команды_N ;;
*) команды_по_умолчанию;;
esac
Значение указанной переменной по очереди сравнивается с приведенными значениями ( значение_1 ,..., значение_N ). Если есть совпадение, то будут выполнены команды, соответствующие значению. Если совпадений нет, то будут выполнены команды по умолчанию. Пример использования case мы рассмотрели выше.
В заключение.
Друзья, мы обзорно рассмотрели, как пишутся сценарии для популярного интерпретатора bash.
Я хочу, чтобы вы не только почитали статью, но и попробовали сами набрать примеры на компьютере. Советую не только повторять приведенные примеры, но и немного их усложнять.
***
Вам понравилось, оказалось полезным? Ставьте, пожалуйста, "лайк"!
Буду рад вашим подпискам.