DevOps_Tools_Guides
  • Readme
  • Git
  • Docker
  • Ansible
  • Bash
  • Vim
Powered by GitBook
On this page
  • Bash
  • Содержание
  • Основы
  • Шебанг
  • Переменные
  • Аргументы командной строки
  • Зарезервированные переменные
  • Условия
  • Циклы
  • Кейс
  • Массивы
  • Словарь
  • Регулярные выражения
  • Функции
  • Debug
  • Полезные инструменты

Bash

PreviousAnsibleNextVim

Last updated 1 year ago

Bash

Содержание

Основы

Шебанг

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

#!/bin/bash

Так же можно использовать утилиту env.

#!/usr/bin/env bash

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

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

Для того чтобы переопределить интерпретатор, установленный в шебанг, нужно запустить явно указав оболочку.

bash <script-name>

Переопределять интерпретатор не рекомендуются, т.к. может привести к неожиданному поведению.

Переменные

Определение локальной переменной и присваивание ей значения. Так же нельзя использовать пробелы между =, т.к. интерпретатор посчитает это за команду. И будет выдана ошибка.

<variable>=<value>

Пример:

var=12345

Если переменная является строкой и содержит пробел, требуется использовать кавычки.

Пример:

var="Hello world"

Для использования переменных перед ними требуется использовать $, иначе будет восприниматься как просто текст.

Примеры:

var=12345
echo $var
> 12345

var=12345
echo var
> var

При использовании одинарных кавычек ', каждый символ будет обрабатываться буквально. При двойных кавычках ", будет происходить подстановка переменных.

Примеры:

var='Hello world'
echo $var
> Hello world

new_var="Hello $var"
echo $new_var
> Hello Hello world


new_var='Hello $var'
echo $new_var
> Hello $var

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

Фигурные скобки - для того, чтобы избавиться от неоднозначности при разборе строки.

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

Аргументы командной строки

При запуске программы можно передать аргументы скрипту.

./<script-name> <arg-1> [<arg-n> ...]

Для того чтобы использовать в скрипте используется $<number>.

  • $0 - имя скрипта Bash.

  • $1-$9 - Первые 9 аргументов для скрипта Bash.

Для использования 10-ого и последующих чисел требуется использовать фигурные скобки.

echo ${10}

Так же есть специальные переменные для удобного использования аргументов.

  • $# - Количество переданных аргументов.

  • $@ - Все аргументы переданные скрипту.

  • $* - все аргументы переданные скрипту, выводятся в строку.

Зарезервированные переменные

Имеются специальные зарезервированные переменные для удобного использования.

Одни из самых часто используемых:

  • $? - Статус выхода последнего процесса.

  • $USER - имя пользователя, выполняющего скрипт.

  • $HOSTNAME - имя хоста, на котором запущен скрипт.

  • $SECONDS - количество секунд с момента запуска скрипта.

  • $RANDOM - Возвращает случайное число каждый раз, когда он упоминается.

  • $LINENO - возвращает текущий номер строки.

  • $EDITOR - текстовый редактор по умолчанию.

  • $HOME - домашний каталог пользователя.

  • $HOSTNAME - hostname машины.

  • $OSTYPE - тип ОС.

  • $PATH - путь поиска программ.

Условия

Конструкция if.

if CONDITION
then
    STATEMENT
elif CONDITION
then
    STATEMENT
esle
    STATEMENT
fi

Так же можно then использовать на этой же строке, но перед ней требуется поставить ;.

if CONDITION; then
    STATEMENT
elif CONDITION; then
    STATEMENT
esle
    STATEMENT
fi

Так же можно отбросить отбросить elif или else, если это не нужно.

Содержимое сразу после if может быть любой командой, если она дает код выхода. Если команда возвращает код выхода 0 (это код успешно выполненной операции), тогда запускается код внутри ветки then. Иначе происходит переходит к следующей ветке.

Для того чтобы использовать условие используются квадратные и круглые скобки.

[ - это команда. Поэтому требуется использовать пробел между ней. Это синтаксический сахар, который проверяет и сравнивает переданные аргументы.

] - это аргумент для команды [, который сообщает для прекращения проверки аргументов. Операторы -lt, -gt являются аргументами. Поэтому знаки > и < странно себя ведут внутри одинарных квадратных скобок. Интерпретатор пытается перенаправить input или output внутри команды.

[[ Двойные квадратные скобки ]] - работают так же, как и одинарные квадратные скобки, но имеют дополнительные возможности вроде лучшей поддержки регулярных выражений.

(( Двойные круглые скобки )) - это конструкция, для осуществления арифметических вычислений.

Их можно использовать даже без if, как пример инкриминтирование счётчика.

(( count++ ))

Круглые скобки тоже при каждом запуске возвращают код выхода. Если результат в скобках равен нулю, возвращается код выхода 1, нулевой результат это fasle. Любой другой результат считается истиной, при нем код выхода будет 0.

Знаки > и < внутри круглых скобок работают правильно. Если сравнение истинно, результат будет 1. В противном случае – 0.

Булевы операторы ! (не), && (и), || (или) так же используются для выражений, как и в других языках.

if [[ CONDITION ]] && ! [[ CONDITION ]] || [[ CONDITION ]]
then
    ...
fi

Часто используемые операторы:

  • -n VAR - True, если длина VAR больше нуля.

  • -z VAR - True, если VAR пусто.

  • STRING_1 = STRING_2 - True, если STRING_1 и STRING_2 равны.

  • STRING_1 != STRING_2 - True, если STRING_1 и STRING_2 не равны.

  • INTEGER_1 -eq INTEGER_2 - True, если INTEGER_1 и INTEGER_2 равны.

  • INTEGER_1 -ne INTEGER_2 - True, если INTEGER_1 и INTEGER_2 не равны.

  • INTEGER_1 -gt INTEGER_2 - True, если INTEGER_1 больше чем INTEGER_2.

  • INTEGER_1 -lt INTEGER_2 - True, если INTEGER_1 меньше, чем INTEGER_2.

  • INTEGER_1 -ge INTEGER_2 - True, если INTEGER_1 равно или больше, чем INTEGER_2.

  • INTEGER_1 -le INTEGER_2 - True, если INTEGER_1 равно или меньше чем INTEGER_2.

  • $string =~ $substring - поиск строки в подстроке.

  • -h FILE - True, если FILE существует и является символической ссылкой.

  • -r FILE - True, если FILE существует и доступно для чтения.

  • -w FILE - True, если FILE существует и доступна для записи.

  • -x FILE - True, если FILE существует и является исполняемым.

  • -d FILE - True, если FILE существует и является каталогом.

  • -e FILE - True, если FILE существует и является файлом, независимо от типа.

  • -f FILE - True, если FILE существует и является обычным файлом (не каталогом или устройством).

  • -s file - True, если существует файл, и не является он пустым.

  • FILE1 -nt FILE2 True, если новее ли FILE1, чем FILE2.

  • FILE1 -ot FILE2 True, если старше ли FILE1, чем FILE2.

  • -O file - True, если существует файл, и является его владельцем текущий пользователь.

  • -G file - True, если существует файл, и соответствует его идентификатор группы идентификатору группы текущего пользователя.

Циклы

Существуют 2 вида for циклов. Bash и Си подобные.

for <variable> in <array>
do
    ...
done

Пример:

Перебор чисел от 1 до 10.

for i in $(seq 1 10)
do
    echo "$i"
done

В параметры цикла можно передавать практически что угодно. Как пример, если нужно обработать файлы нужной директории, то можно передать команду $(ls /path/to/dir), и каждый файл будет отдельно обрабатываться.

Цикл из си.

for (( i=0; i<10; i++ ))
do
    ...
done

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

Цикл while.

while [[ CONDITION ]]
do
    ...
done

В циклах можно использовать стандартные слова break и continue.

Пример:

Использование continue при выводе чисел.

for i in $(seq 1 10)
do
    if [[ $i -eq 5 ]]
    then
        continue;
    fi
    echo "$i"
done

Кейс

Конструкция case.

case EXPRESSION in

  PATTERN_1)
    STATEMENTS
    ;;

  PATTERN_2)
    STATEMENTS
    ;;

  PATTERN_N)
    STATEMENTS
    ;;

  *)
    STATEMENTS
    ;;
esac

Каждая конструкция должна оканчиваться ;;.

Кейс с * отвечает любые другие возможные значения.

В одном шаблоне можно использовать несколько возможных вариантов.

case EXPRESSION in

  PATTERN_1 | PATTERN_2 | PATTERN_3)
    STATEMENTS
    ;;

Массивы

Массивы можно перебирать двмя способами:

  • * - вывод всех элементов в одной строке.

  • @ - позволяет разбить массив на отдельные элементы.

Конструкции для вывода массивов:

  • ${array[@]} - все записи в массиве.

  • ${!array[@]} - все индексы в массиве.

  • ${#array[@]} - количество записей в массиве.

  • ${#array[0]} - длина первой записи (нумерация с нуля).

Вывод массива используя индексы.

array=(1 3 4 6 7 10 15 20)

for i in "${!array[@]}"
do
    echo "index - $i, element - ${array[i]}"
done

Вывод массива используя элементы массива.

array=(1 3 4 6 7 10 15 20)

for elem in "${array[@]}"
do
    echo "element - ${elem}"
done

Вывод количества элеметов в массиве.

echo "${#array[@]}"

Вывод определённого элемента массива.

echo "${array[0]}"

Вывод диапазон элементов.

echo "${array[&]:0:5}"

Запись в массив вывода из команды.

list=( $(ls /) )

Перезапись определённого элемента.

array[0]=3

Добавление элемента в массив.

array+=(25)

Для удаления из массива элемента используется специальная команда unset.

unset "array[2]"

Сортировка массива по возрастанию. Если требуется отсортировать по убыванию нужно добавить флаг -r.

array=(10 85 63 3 4 6 7 10 15 20)
array_s=($(printf '%s\n' "${array[@]}" | sort -n))
echo "${array_s[@]}"

Массивы не требуют, чтобы последовательность элементов в массиве была непрерывной. Обращение к неинициализированным элементам дает пустую строку.

array=(1 3 4 6 7 [10]=10 15 [20]=20)

for i in "${!array[@]}"
do
    echo "index - $i, element - ${array[i]}"
done
echo "count element - ${#array[@]}"

Вывод.

index - 0, element - 1
index - 1, element - 3
index - 2, element - 4
index - 3, element - 6
index - 4, element - 7
index - 10, element - 10
index - 11, element - 15
index - 20, element - 20
count element - 8

Словарь

Словарь создаётся с помощью массивов.

declare -A dictionary=([key1]=75 [key2]=82 [key3]=83 [key4]=72)

Вывод всех элементов словаря.

for key in "${!dictionary[@]}"; do
    echo "$key - ${dictionary[$key]}"
done

Обращение к определённому элементу словаря.

echo "${dictionary[key2]}"

Регулярные выражения

  • . - любой символ.

  • [ ] - диапазон символов.

  • [^ ] - все символы, кроме указанных в фигурных скобках.

  • * - любое количество символов, в том числе и ноль.

  • + - один или несколько символов или выражений.

  • ? - ноль или один символ или выражение.

  • {n} - предыдущий символ должен повторяться n раз.

  • {n,} - предыдущий символ может повторяться не меньше n символов.

  • {n m} - предыдущий символ может повторяться от n до m раз.

  • {,m} - предыдущий символ может повторяться не более m раз.

  • \ - экранирование спецсимволов.

  • ^ - начало строки.

  • $ - конец строки.

  • ^$ - соответствие пустой строки.

Альтернативный способ указания диапазонов.

  • [:alnum:] - алфавитные символы и цифры. Эквивалентно выражению [A-Za-z0-9].

  • [:alpha:] - символы алфавита. Эквивалентно выражению [A-Za-z].

  • [:blank:] - символ пробела или символ табуляции.

  • [:cntrl:] - управляющие символы (control characters).

  • [:digit:] - набор десятичных цифр. Эквивалентно выражению [0-9].

  • [:print:] (печатаемые символы) - набору символов из диапазона ASCII 32 - 126.

  • [:graph:] (печатаемые символы) - соответствует набору символов из диапазона ASCII 33 - 126. То же самое, что и [:print:], за исключением символа пробела.

  • [:lower:] - набор алфавитных символов в нижнем регистре. Эквивалентно выражению [a-z].

  • [:upper:] - наборы символов алфавита в верхнем регистре. Эквивалентно выражению [A-Z].

  • [:space:] - пробельные символы (пробел и горизонтальная табуляция).

  • [:xdigit:] - набор шестнадцатеричных цифр. Эквивалентно выражению [0-9A-Fa-f].

Функции

Объявление функции.

function <function-name> {
}

Или.

function <function-name>() {
}

Или.

<function-name>() {
}

Возвращения значения.

function <function-name> {
    return $<return-value>
}

Принять возвращаемое значение функции.

result=$(<function-name>)

Или.

<function-name>
echo "$?"

Передача аргументов функции.

<function-name> $value 10 20

Для обработки переменных, которых передали функции, используется $ и номер переданной переменной.

function <function-name>() {
    echo $1
}

<function-name> "test"

Примеры:

Функция сложения двух чисел.

function sum() {
    return $(( $1 + $2 ))
}

result=$(sum 10 20)
echo $result

Debug

Для того чтобы использовать debug и понимать, что происходит в программе, нужно в начале програмы прописать.

trap 'echo "# $BASH_COMMAND";read' DEBUG

После этого будет выводиться команда и вывод команды если он есть.

Полезные инструменты

  • shellcheck - инструмент для статического анализа кода и повышения качества скриптов.

Использование локально.

shellcheck your_script.sh

Либо его можно использовать .

онлайн
Полезные инструменты
Основы
Шебанг
Переменные
Аргументы командной строки
Зарезервированные переменные
Условия
Циклы
Кейс
Массивы
Словарь
Регулярные выражения
Функции
Debug
Наверх
Наверх
Наверх
Наверх
Наверх
Наверх
Наверх
Наверх
Наверх
Наверх
Наверх
Наверх
Наверх