Pull to refresh

Консоль в массы. Переход на светлую сторону. Bash

Reading time 6 min
Views 54K
keep-calm-and-bin-bash

Вступление


Удобство использования того или иного инструмента заключается в том, насколько он помогает в решении конкретной задачи. Также важно, чтобы мы могли настроить этот инструмент под свои нужды. Приятным бонусом будет и тот факт, что мы можем расширить и дополнить новыми возможностями наш инструмент.

Мы добрались до самой интересной и увлекательной темы — это скрипты на bash. Когда вы запускаете терминал, внутри него работает специальная программа-оболочка — shell (англ) — интерпретатор команд. Shell понимает все команды, которые вы вводите с клавиатуры, и обрабатывает их. Также выводит сообщения об ошибках, следит за корректностью команд и их синтаксисом. Примером таких команд могут быть: сменить директорию, создать новую директорию, добавить текстовый файл, отредактировать текстовый файл, сохранить изменения и другие.

Программ-оболочек довольно много. Одна из первых удачных реализаций называется sh. Ее разработал Стивен Борн в 1977 году (wiki). В 99% случаев, когда вы работаете за компьютером под управлением OS *nix, оболочкой по умолчанию, которая обрабатывает команды, будет bash. Конечно, есть еще такая оболочка как zsh и другие, но это уже совсем другая история.

Важный момент. Данная статья не является исчерпывающим руководством по скриптам на bash. Главная цель — это рассмотреть основы программирования на bash, показать примеры, дать читателю базовые знания, которых хватит, чтобы двигаться дальше. В конце статьи есть полезные ссылки и вы сможете более подробно изучить данную тему.

Основы


Первый раздел посвящен основам. Рассмотрим с чего должен начинаться любой скрипт. Как определяются переменные и как менять значения этих переменных. Также разберемся как передавать аргументы скрипту и обрабатывать эти аргументы внутри скрипта. Следующий раздел — это ветвления. И последний, но не менее важный раздел — циклы.

Любой скрипт на bash должен начинаться со строки:

#!/bin/bash

Тем самым мы говорим интерпретатору какую программу вызвать, если скрипт исполняемый.

Для улучшения переносимости кода следует указывать такой вариант первой строки:

#!/usr/bin/env bash

Не гарантируется, что на различных системах путь к bash будет одинаковым. Указывая env мы защищаем себя от таких неожиданностей. Повторюсь, это в том случае, если вы планируете использовать свои скрипты на разных системах, компьютерах и т.д. Если такой необходимости нет, первый вариант отлично подойдет. Во всех примерах используется первый вариант.

По умолчанию все файлы, которые создает пользователь, не являются исполняемыми. Мы должны явно указать для конкретного файла этот параметр при помощи команды:

chmod +x <filename>

Можно запустить скрипт и без этого параметра при помощи команды:

bash <filename>

Переменные


Переменная — это именованная область в памяти. Это значит, что у переменной есть имя и оно ссылается на определенную ячейку памяти компьютера. Обычно переменные используются для хранения какой-то информации. Любая переменная состоит из двух частей: имя и значение.

Имя переменной:


  • буквы, цифры, знак нижнего подчеркивания (_)
  • не может начинаться с цифры

Значение переменной:


  • числа, строки (если есть пробелы, то в кавычках), отдельные символы

Создание (перезапись) переменной:


path="$HOME"

Обратите внимание, что перед знаком равно и после него не должно быть пробелов.

Чтение переменной:


"$path" или "${path}"

В большинстве случаев оба варианта работают одинаково. В отдельных случаях, при возникновении неоднозначности интерпретации, корректно будет работать только такая форма записи: "${path}"

Передача аргументов скрипту:


./script.sh arg1 arg2 arg3 … argN

Обработка аргументов внутри скрипта:


"$1" # первый аргумент
"$2" # второй аргумент
"$0" # имя скрипта
"$#" # количество аргументов
"$*" # все аргументы в виде одной строки (слова)
"$@" # аналогичен $*, но при этом каждый параметр представлен как отдельная строка (слово),
   # т.е. параметры не подвергаются какой либо интерпретации

Ну что, пришло время написать первый скрипт. Как это и должно быть, скрипт будет выводить на экран пользователя строку «Hello, world!».

Вот так просто, на bash можно реализовать пример с «Hello, world!». Напоминаю, что все примеры вы можете найти в репозитории. Давайте рассмотрим еще один пример. На этот раз поработаем с переменными, а также с аргументами, которые пользователь передает скрипту.

Обратите внимание на то, что все программы, написанные на bash, обычно имеют расширение .sh.

Ветвления


С основами и переменными немного разобрались. Теперь перейдем к ветвлениям. Для работы с ветвлениями в bash нам доступны следующие конструкции:

  1. if
  2. if/else
  3. if/elif/else
  4. 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, которая не объявлена до этого. Эта переменная создается динамически и потом считывается ее значение.

Полезные ссылки


  1. Basics of Bash
  2. bash-handbook
  3. Подводные камни Bash
  4. Advanced Bash-Scripting Guide [en] ( Konkase спасибо за ссылку )
  5. Advanced Bash-Scripting Guide ( aso спасибо за ссылку )
  6. Shell Style Guide от Google ( leoismyname спасибо за ссылку )
  7. В чём смысл и преимущества #!/usr/bin/env? ( Borz спасибо за ссылку )
  8. Learn the Command Line
  9. The Command Line Crash Course
  10. Linux Command Line in Русский
  11. Basic Unix commands

Вместо заключения


На этой позитивной ноте мы закончим знакомство с bash. Данной информации достаточно, чтобы реализовать простенькие скрипты, а также автоматизировать повседневные задачи.

Забегая немного наперед, скажу, что в следующей статье будет меньше теории и еще больше примеров, как автоматизировать рутинные задачи при помощи bash скриптов. Следите за обновлениями.

На этом все. Спасибо за внимание. Кто дочитал до конца, отдельное спасибо. До встречи в следующей статье.

UPD. Текст статьи обновлен на основании обсуждений в комментариях. Спасибо всем, кто принимал активное участие в обсуждениях. Вы сделали статью еще лучше. И не только статью.
Tags:
Hubs:
+45
Comments 108
Comments Comments 108

Articles