Вступление
Удобство использования того или иного инструмента заключается в том, насколько он помогает в решении конкретной задачи. Также важно, чтобы мы могли настроить этот инструмент под свои нужды. Приятным бонусом будет и тот факт, что мы можем расширить и дополнить новыми возможностями наш инструмент.
Мы добрались до самой интересной и увлекательной темы — это скрипты на bash
. Когда вы запускаете терминал, внутри него работает специальная программа-оболочка — shell
(англ) — интерпретатор команд. Shell понимает все команды, которые вы вводите с клавиатуры, и обрабатывает их. Также выводит сообщения об ошибках, следит за корректностью команд и их синтаксисом. Примером таких команд могут быть: сменить директорию, создать новую директорию, добавить текстовый файл, отредактировать текстовый файл, сохранить изменения и другие.
Программ-оболочек довольно много. Одна из первых удачных реализаций называется sh
. Ее разработал Стивен Борн в 1977 году (wiki). В 99% случаев, когда вы работаете за компьютером под управлением OS *nix
, оболочкой по умолчанию, которая обрабатывает команды, будет bash. Конечно, есть еще такая оболочка как zsh
и другие, но это уже совсем другая история.
Важный момент. Данная статья не является исчерпывающим руководством по скриптам на bash. Главная цель — это рассмотреть основы программирования на bash, показать примеры, дать читателю базовые знания, которых хватит, чтобы двигаться дальше. В конце статьи есть полезные ссылки и вы сможете более подробно изучить данную тему.
Основы
Первый раздел посвящен основам. Рассмотрим с чего должен начинаться любой скрипт. Как определяются переменные и как менять значения этих переменных. Также разберемся как передавать аргументы скрипту и обрабатывать эти аргументы внутри скрипта. Следующий раздел — это ветвления. И последний, но не менее важный раздел — циклы.
Для начала нам нужно знать где находится bash. Эта информация нам понадобиться при написании самих скриптов. Чтобы узнать где находиться bash, выполните следующую команду:
which bash # где находится bash
Любой скрипт на bash должен начинаться со строки:
#!/bin/bash
Тем самым мы говорим интерпретатору какую программу вызвать, если скрипт исполняемый. По умолчанию все файлы, которые создает пользователь, не являются исполняемыми. Мы должны явно указать для конкретного файла этот параметр при помощи команды:
chmod +x <filename>
Переменные
Переменная — это именованная область в памяти. Это значит, что у переменной есть имя и оно ссылается на определенную ячейку памяти компьютера. Обычно переменные используются для хранения какой-то информации. Любая переменная состоит из двух частей: имя и значение.
Имя переменной:
- буквы, цифры, знак нижнего подчеркивания (
_
) - не может начинаться с цифры
Значение переменной:
- числа, строки (если есть пробелы, то в кавычках), отдельные символы
Создание (перезапись) переменной:
path=$HOME
Обратите внимание, что перед знаком равно и после него не должно быть пробелов.
Чтение переменной:
$path
Передача аргументов скрипту:
./script.sh arg1 arg2 arg3 … argN
Обработка аргументов внутри скрипта:
$1 # первый аргумент
$2 # второй аргумент
$0 # имя скрипта
$# # количество аргументов
Ну что, пришло время написать первый скрипт. Как это и должно быть, скрипт будет выводить на экран пользователя строку «Hello, world!».
Вот так просто, на bash можно реализовать пример с «Hello, world!». Напоминаю, что все примеры вы можете найти в репозитории. Давайте рассмотрим еще один пример. На этот раз поработаем с переменными, а также с аргументами, которые пользователь передает скрипту.
Обратите внимание на то, что все программы, написанные на bash, обычно имеют расширение .sh
.
Ветвления
С основами и переменными немного разобрались. Теперь перейдем к ветвлениям. Для работы с ветвлениями в bash нам доступны следующие конструкции:
if
if/else
if/elif/else
case/in/esac
Первые три варианта схожи и каждая следующая конструкция дополняет предыдущую. Рассмотрим самый простой вариант:
Обратите внимание на то, что в конце каждой строки отсутствует точка с запятой. Есть возможность писать условия (и не только) в одну строку, тогда точка с запятой нужны.
При работе с ветвлениями нам нужно как-то проверять, пуста строка или нет, равно число нулю или не равно, работаем мы с файлом или это директория. Для таких задач в bash существует свой синтаксис. Я его разделил на четыре категории: строки, числа, файлы, логические. Давайте рассмотрим их.
Условия (строки):
Условия (числа/строки):
Условия (файлы):
Условия (логические):
Вариант if/else
мы пропустим. А вот if/elif/else
предлагаю рассмотреть на примере:
Скрипт ожидает получить на вход один аргумент — имя файла или имя директории. Дальше идет проверка, действительно ли это файл или директория. Если да, то выполняем удаление. Если переданный аргумент не является ни файлом ни директорией, выводим сообщение пользователю, что удаление невозможно.
Нам осталось рассмотреть последний вариант ветвления — это case/in/esac
. Если проводить аналогию с JavaScript, то это вариант реализации switch/case
. Рассмотрим эту конструкцию тоже на примере.
Данный скрипт ожидает получить два числовых аргумента: единицу и двойку. И в зависимости от того, какой аргумент будет первым, создается файл или директория. Также есть проверка на количество аргументов, которые передал пользователь. Количество аргументов не должно быть меньше двух. Если пользователь передал неверные аргументы, выводим ему сообщение об этом. За это отвечает значение по умолчанию.
Циклы
Следующий раздел, который мы рассмотрим — это работа с циклами. Для организации циклов в арсенале bash присутствуют такие конструкции: for/in
и while
.
Давайте рассмотрим синтаксис for/in
:
i
— это название переменной, в которую будет передаваться элемент массива. array
— это сам массив. На каждой последующей итерации i
получает следующее значение из массива. Рассмотрим пример:
Есть список значений: 1 2 3 4 5
. Запускаем цикл, который проходится по всем значениям. Создаем переменную file_name
. Потом проверяем существует ли файл с таким именем. Если файла нет — создаем его, если есть пропускаем шаг создания.
Вы могли заметить слово continue
— это ключевое слово. Позволяет пропустить итерацию и продолжить работу дальше. Также есть ключевое слово break
— прерывает выполнение скрипта. Используются эти ключевые слова только в контексте if/else
.
Следующая конструкция, которую мы рассмотрим для работы с циклами, будет while
:
Предлагаю сразу же рассмотреть пример:
В данном примере есть две строки с ключевым словом read
. Рассмотрим более подробно как работают эти строки. А именно: строка номер двенадцать и строка номер восемь. Начнем со строки номер двенадцать. Пока переменная $again
равна значению "yes"
, программа просит ввести имя пользователя и выводит его на экран. После этого скрипт спрашивает, хотим ли мы продолжить. И так до тех пор, пока пользователь не введет любую другую строку вместо yes
или просто нажмет Enter
. Но гораздо интереснее код на строке номер восемь. Присутствует переменная $name
, которая не объявлена до этого. Эта переменная создается динамически и потом считывается ее значение.
Полезные ссылки
- Basics of Bash
- bash-handbook
- Подводные камни Bash
- Learn the Command Line
- The Command Line Crash Course
- Linux Command Line in Русский
- Basic Unix commands
Вместо заключения
На этой позитивной ноте мы закончим знакомство с bash. Данной информации достаточно, чтобы реализовать простенькие скрипты, а также автоматизировать повседневные задачи.
Забегая немного наперед, скажу, что в следующей статье будет меньше теории и еще больше примеров, как автоматизировать рутинные задачи при помощи bash скриптов. Следите за обновлениями.
На этом все. Спасибо за внимание. Кто дочитал до конца, отдельное спасибо. До встречи в следующей статье.
Автор: var_bin