Перед чтением этой статьи рекомендуем ознакомиться с предыдущими публикациями из серии Основы написания bash-скриптов: Знакомство с bash, Часть 1. Bash-скрипты. Основные команды и рекомендации
В третьей статье серии о bash-скриптах подробно рассматриваем часть компонентов скрипта:
Переменные
В программировании переменная — это именованное место хранения (адрес в памяти) определённых данных: числа, строки (последовательности символов), выражения с использованием других переменных, функции и т. д.
При этом bash не делит данные на типы, в отличие от многих других языков программирования. По сути, в качестве значений переменных хранятся строки, но если строка содержит только цифры, bash позволяет проводить над ней арифметические операции.
Строка — непрерывная последовательность символов, в том числе нечитаемых (например, управляющих последовательностей). Строка может иметь длину в один символ или нулевую длину. |
При именовании и вызове переменных следует учитывать, что регистр букв имеет значение: number и Number
— это разные переменные.
В bash предусмотрены переменные двух типов: переменные окружения (environment variables) и пользовательские (user-defined variables). Как правило, переменные окружения записываются прописными (большими) буквами: $USER, $PATH
.
(В функциях bash различают также глобальные и локальные переменные, о которых будет рассказано в одной из следующих статей в разделе Функции.)
Пользовательские переменные создаёт автор скрипта. В их названия можно включать буквы (предпочтительно строчные, чтобы случайно не изменить значения переменных окружения), цифры и знаки подчёркивания. При этом названия не могут начинаться с цифр.
Если в переменной сохранено, например, имя пользователя lite
, можно получить её значение так:
$ echo ${USER}
Выводимый результат:
lite
(Здесь и далее для примеров используется окружение с непривилегированным пользователем lite
).
Символ $
перед именем переменной указывает, что будет получено значение переменной.
В следующем скрипте вывод команды whoami
записывается в переменную user
, а затем это значение выводится на консоль при помощи команды echo
:
#!/bin/bash
user=$(whoami)
echo "Hello ${user}!"
Выводимый результат: Hello lite!
Замена имени переменной на её значение при помощи выражения ${variable_name}
или $variable_name
называется подстановкой значения переменной.
Внимание: при присваивании значений переменным важно отсутствие пробелов. Команда user = $(whoami)
, например, не будет работать корректно.
Комментарии
Символ # в начале строки указывает, что эта строка является комментарием: всё, что находится в строке после #, оболочка игнорирует (если этот символ не экранирован). Комментарии помогают читателю понять код, то есть служат минимальной документацией для автора и для тех, кто будет работать со скриптом — например, если он помещён в публичный репозиторий.
Комментарии можно добавлять перед блоком кода — в этом случае они описывают смысл последовательности действий или функции:
#!/bin/bash
# Скрипт резервного копирования путём архивирования
source="/home/$USER/Documents"
destination="/media/MySSD/backup/Documents-backup-$(date +%Y-%m-%d
).tar.gz"
tar -czf "$DESTINATION" "$SOURCE"
Смысл скрипта:
- Значение переменной
source
— путь к каталогу, для которого создаётся резервная копия. - Значение переменной
destination
— путь к созданному в результате архиву. При этом имя архива будет состоять из имени исходного каталога, слова backup и компонентов вывода командыdate: %Y
— текущий год,%m
— месяц, %d — сегодняшний день. - Команда
tar
с ключами-c
(cоздать),-z
(заархивировать cредствами пакета gzip),-f
(сохранить по указанному пути) использует переменнуюsource
как путь к исходному каталогу, переменнуюdestination
— как путь к создаваемому архиву.
Комментарии можно оставлять и в конце строки с командой — в этом случае поясняется конкретная команда:
$ mv hosts hosts-old # Переименовать файл hosts в hosts-old
Bash игнорирует строку, в начале которой есть символ #
, до переноса строки. Следующие строки интерпретируются как обычно.
Для ввода комментария из нескольких строк удобно использовать не символ #
в начале каждой строки, а такую запись:
: '
многострочный
комментарий
'
Кроме того, в процессе написания скрипта можно исключать некоторые команды, группы команд или управляющие конструкции из последовательности выполнения — например, чтобы поочерёдно запускать скрипт с несколькими вариантами одной команды и находить оптимальный, или для отладки — выяснения причин ошибок при выполнении.
Чтобы интерпретатор пропускал команду при выполнении скрипта, добавьте в начале строки с командой символ #:
# Создание файла. Эта команда будет выполнена:
touch new_file.txt
# Копирование файла. Эта команда будет пропущена:
# cp old_file.txt new_location/
Подстановочные знаки и шаблоны поиска
Подстановочный знак, или метасимвол (wildcard) — это символ, который используется для обозначения любого символа. Эти знаки удобно использовать для поиска и фильтрации файлов по названиям. В оболочках Unix подстановка специальных символов для получения имён файлов называется globbing (поиск по шаблонам).
Например, в результате выполнения команды
ls *.sh
будут отображены все файлы с расширением .sh
в текущем каталоге. При этом звёздочка * может обозначать любое количество символов.
Подстановочные знаки можно использовать с разными командами:
grep -l 'ERROR' *.log
Эта команда выведет на экран все названия файлов с расширением .log
в текущем каталоге, в которых встречается строка ERROR
. Ключ -l
указывает, что нужно выводить только названия файлов, а не все строки в файлах, где встречается указанное слово.
Можно также искать символы, которые входят в диапазоны букв или цифр, например:
mv [a-z]*.jpg /target/directory
Эта команда переместит все файлы из текущего каталога с расширением .jpg, названия которых начинаются со строчной буквы в диапазоне от a до z, в каталог /target/directory
.
Другие часто используемые подстановочные знаки
Подстановочный знак | Назначение |
| Один любой символ.
|
| Означает «нет» или отрицание.
|
| Означает один символ из перечисленных в квадратных скобках.
|
Пользовательский ввод
Иногда в скрипте требуется прочитать значение, введённое пользователем. Такие значения можно записывать в файлы, сравнивать с эталонными значениями (например, при валидации пароля), применять для текущей задачи (например, выбора из нескольких вариантов действий).
Команда чтения read
читает всё, что вводит пользователь после приглашения до нажатия клавиши Enter
, и помещает считанное в назначенную для этого переменную.
Синтаксис в общем виде:
read <опции> <имяпеременной>
Следующий скрипт предлагает ввести 10 цифр телефона без +7 — кода страны, проверяет, является ли содержимое ввода строкой из 10 цифр, и сообщает о корректности или некорректности ввода:
#!/bin/bash
read -p "Введите номер телефона (10 цифр, без пробелов, без +7): " input
if [[ $input = ^[0-9]{10}$ ]];
then
echo "Номер телефона введён корректно."
else
echo "Номер телефона введён некорректно."
fi
- После запуска скрипта в консоли отображается указание:
Введите номер телефона (10 цифр, без +7):
- Пользователь вводит несколько символов (либо не вводит символы) и нажимает
Enter
. - Команда
read
считывает введённое пользователем значение и помещает его в переменную input. При помощи условного оператора
if
(об условных операторах расскажем в одной из следующих статей) скрипт проверяет, соответствует ли введённое значение условию «строка из 10 цифр».а) Если условие выполняется, отображается сообщение:
Номер телефона введён корректно
.б) Если условие не выполняется, отображается сообщение:
Номер телефона введён некорректно
.
Заключение
В статье рассмотрены многие важные понятия, необходимые для начала создания bash-скриптов: переменные, подстановочные знаки, пользовательский ввод, комментарии.