Основы программирования Bash #

Васильев Андрей Михайлович, 2025

Версии презентации

Базовый цикл работы #

Bash выполняет каждую строку как отдельную команду, поведение идентично работе в в эмуляторе терминала

#!/bin/bash

touch file1
mkdir trash
mv file1 trash
rm -rf trash
mkdir trash
echo "Файл удален!"

Документация #

Расширение строк в Bash #

  • Строка, поступившая на вход интерпретатора разделяется на слова
  • К каждому слову применяется процедура расширения строки
  • К одному слову может быть применено несколько расширений
  • У каждого слова удаляются кавычки

Получившееся строка выполняется согласно обычным правилам

Выполняются расширения в следующем порядке:

  • Расширение скобок
  • Расширение тильды
  • Расширение переменных
  • Замена команд
  • Арифметическое расширение
  • Разделение на слова
  • Расширение путей

Расширение скобок #

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

Формат списка: [преамбула]{компонент-1,компонент-2}[послесловие]

  • Преамбула и послесловие являются необязательными
  • Внутри компонентов могут быть другие шаблоны расширения строк
$ echo a{b,c,d}e
abe ace ade

Формат последовательности: [преа]{старт..конец[..шаг]}[после]

  • Старт и конец могут быть как целыми числами, так и строками
  • Необязательный компонент шаг является целым числом
$ echo result-{2010..2012}-{01..12..6}
result-2010-01 result-2010-07 result-2011-01 result-2011-07
  result-2012-01 result-2012-07

Расширение тильды #

Если слово начинается с символа ~, то все символы до / или до конца слова считаются префиксом

  • ~ — заменяется значением $HOME
  • ~/foo — заменяется значением $HOME/foo
  • ~fred/foo — заменяется путём до каталога foo в домашнем каталоге пользователя fred
  • ~+/foo — заменяется значением $PWD/foo
  • ~-/foo — заменяется значением ${OLDPWD}/foo
  • ~N — заменяется выводом команды dirs +N
  • ~+N — заменяется выводом команды dirs +N
  • ~-N — заменяется выводом команды dirst -N

Расширение переменных #

Слово, начинающееся с $, обозначает расширение параметра, замену команды или арифметическое расширение. У последних двух следующим символом идёт (

  • Символы до конца слова считаются названием переменной
  • Символы, заключённые между { и } считаются названием переменной
$ echo $PWD
/home/user
$ echo ${PWD}
/home/user

Если переменная не настроена, то заменой будет пустая строка

Bash предоставляет огромные возможности по работе с переменными: значение по умолчанию, значение другого параметра, обращение с исключением, замена существующего значения, обращение к подстроке, работа с массивами, замена подстроки

Замена команд #

В рамках данной замены сначала выполняется команда, затем содержимое её стандартного вывода помещается на место строки

Существует 2 формы описания: $(команда) и `команда`. Первая форма, более свежая, имеет меньше специальных особенностей исполнения

  • Замены команд могут быть вложенными
  • Если замена расположена внутри двойных кавычек, то над результатом не выполняются разбиение на слова и расширение путей
$ echo 02 2020 > param.txt
$ cal -n 2 $(< param.txt)
cal -n 2 $(< param.txt)
    Февраль 2020            Март 2020
Пн Вт Ср Чт Пт Сб Вс  Пн Вт Ср Чт Пт Сб Вс
                1  2                     1
 3  4  5  6  7  8  9   2  3  4  5  6  7  8
10 11 12 13 14 15 16   9 10 11 12 13 14 15
17 18 19 20 21 22 23  16 17 18 19 20 21 22
24 25 26 27 28 29     23 24 25 26 27 28 29
                      30 31

Арифметическое расширение #

Позволяет выполнить математическую операцию, результат которой заменит выражение, форма записи: $(( выражение ))

  • Все слова внутри выражения проходят расширение параметров, замены команд и удаление кавычек
  • Арифметические расширения могут быть вложенными
$ echo $(( 24 + 18 ))
42
  • Вычисление происходит над целыми числами без проверки на переполнение
  • Поддерживается большинство операций из языка Си:
    • Префиксные и постфиксное уменьшение и увеличение значений
    • Возвещение в степень
    • Умножение, деление, остаток от деления, сложение, вычитание
    • Побитовая операции
    • Логические операции

Разделение на слова #

Интерпретатор анализирует результаты расширения параметров, замены команд и арифметического расширения, которые не были внутри двойных кавычек

Разделение результатов происходит по значению переменной $IFS, если не установлено, то её значением считается <space><tab><newline>

Данные элементы удаляются из начала и конца строки, а также используются для разделения на слова

Расширение путей #

На этом этапе в каждом слове происходит поиск символов *, ? и [. Если данные символы встречаются и не находятся внутри кавычек, то выполняется расширение

Шаблоны расширений пишутся на собственном языке, называемым GLOB, который похож на регулярные выражения, но отличается от них

  • Большинство символов не меняют своего значения
  • Символ * соответствует любой строке, включая пустую
  • Символ ? соответствует одному любому символу
  • Блок [...] соответствует одному символу, перечисленному внутри скобок
  • Внутри блока можно указывать символы из POSIX-стандарта:
    • [[:alnum:]] — буква или число
    • [[:lower:]] — буква в нижнем регистре
$ ls
a.txt  b.md  c.md  d.txt
$ echo *.txt
a.txt d.txt