Полное руководство по специальным конструкциям, переменным и расширениям Bash

Обзор

В этой статье систематически рассмотрены все специальные конструкции, переменные, правила расширения и управляющие структуры в Bash.


Обозначения переменных

Динамические или зависящие от среды значения обозначаются как <<переменная>>, при этом для каждой конструкции приведён пример использования.

Имя переменной Пример Описание
<<var>> name, path, user Имя произвольной переменной
<<default>> guest, 8080 Значение по умолчанию
<<pattern>> *.txt, */ Шаблон файлов или строк
<<offset>> 0, 3 Начальная позиция подстроки (с нуля)
<<length>> 4, 10 Длина подстроки
<<prefix>> ENV_, HOST Префикс имени переменной
<<index>> 0, 1, 2 Индекс массива или ключ ассоциативного массива
<<file>> /tmp/test.txt Путь к файлу

Шаг 1: Специальные символы (метасимволы)

Символ Значение Пример
* Совпадение с любой строкой ls *.txt
? Совпадение с одним символом ls ?.sh
[a-z] Диапазон символов ls [A-Z]*
{a,b} Расширение фигурных скобок mv {foo,bar}
{1..3} Последовательность touch file{1..3}.txt
$ Подстановка переменной echo $HOME
! (отрицание) Логическое отрицание [[ ! -f test.txt ]]
! (история) Расширение истории !10
~ Домашний каталог cd ~
; Последовательное выполнение pwd; ls
&& Выполнение при успехе make && echo OK
` `
& Фоновое выполнение sleep 5 &
` ` Конвейер
> Перенаправление вывода echo hi > out.txt
>> Добавление в файл echo hi >> out.txt
< Перенаправление ввода wc -l < file.txt
() Подоболочка (cd /tmp; ls)
{} Тот же процесс { echo A; echo B; }
\ Экранирование echo \$HOME
' ' Без подстановки echo '$USER'
" " С подстановкой echo "$USER"

Шаг 2: Специальные переменные

Переменная Содержание Пример
$0 Имя скрипта echo $0
$1〜$9 Аргументы echo $1
$@ Массив аргументов for a in "$@"; do echo $a; done
$# Количество аргументов echo $#
$? Код завершения последней команды ls /nope; echo $?
$$ PID текущего процесса echo $$
$! PID последнего фонового процесса sleep 10 & echo $!
$- Активные опции оболочки echo $-
$_ Последний аргумент предыдущей команды echo $_
$PPID PID родительского процесса echo $PPID
$RANDOM Случайное число (0–32767) echo $RANDOM
$SECONDS Секунды с момента запуска echo $SECONDS
$FUNCNAME Имя функции f(){ echo $FUNCNAME; }; f
$PIPESTATUS[@] Коды завершения конвейера `ls

Шаг 3: Расширение параметров

Синтаксис Значение Пример
${<<var>>} Подстановка значения name=user; echo ${name}
${<<var>>:-<<default>>} Значение по умолчанию echo ${user:-guest}
${<<var>>:=<<default>>} Присвоение по умолчанию echo ${port:=8080}
${<<var>>:+alt} Альтернатива при определении x=1; echo ${x:+OK}
${<<var>>:?msg} Ошибка при неопределённости echo ${config:?missing}
${#<<var>>} Длина строки name=user; echo ${#name}
${<<var>>%<<pattern>>} Удалить с конца (коротко) path=/a/b/c; echo ${path%/*}
${<<var>>%%<<pattern>>} Удалить с конца (длинно) echo ${path%%/*}
${<<var>>#<<pattern>>} Удалить с начала (коротко) echo ${path#*/}
${<<var>>##<<pattern>>} Удалить с начала (длинно) echo ${path##*/}
${<<var>>/<<pattern>>/<<repl>>} Замена первого совпадения echo ${msg/foo/bar}
${<<var>>//<<pattern>>/<<repl>>} Замена всех совпадений echo ${msg// /_}
${<<var>>:<<offset>>} Подстрока с позиции s=abcdef; echo ${s:2}
${<<var>>:<<offset>>:<<length>>} Подстрока длиной echo ${s:1:3}
${!<<prefix>>*} Переменные с префиксом HOST1=x; HOST2=y; echo ${!HOST*}
${!<<var>>} Косвенная подстановка ref=NAME; NAME=user; echo ${!ref}
${<<var>>,} / ${<<var>>^^} Изменение регистра n=abc; echo ${n^^}
${<<var>>@Q} Квотирование x='abc'; echo ${x@Q}

Шаг 4: Массивы и ассоциативные массивы

arr=(a b c)
echo ${arr[<<index>>]}
echo ${#arr[@]}
for i in "${arr[@]}"; do echo $i; done

declare -A map
map[<<index>>]=100
map[name]=user
echo ${map[<<index>>]}
echo ${!map[@]}

Шаг 5: Арифметические операции

x=5
y=3
echo $((x + y))
((x *= 2))
echo $x

Шаг 6: Условия и сравнения

if [ "$USER" = "root" ]; then echo root; fi
if [ "$x" -lt 10 ]; then echo "small"; fi
if [ -f /etc/passwd ]; then echo "exists"; fi
s="hello123"
[[ $s =~ [0-9]+ ]] && echo "contains number"

Шаг 7: Подстановка команд и подоболочка

echo "Today: $(date +%Y-%m-%d)"
(cd /tmp; ls)

Шаг 8: Перенаправление и файловые дескрипторы

echo "Hello" > <<file>>
echo "Append" >> <<file>>
wc -l < <<file>>
ls /notfound 2> err.log
echo "OK" >&2
exec 3> custom.log
echo "via fd3" >&3
exec 3>&-

Пояснение: Файловые дескрипторы (FD)

FD Название Описание Пример
0 stdin Ввод с клавиатуры или файла < file.txt
1 stdout Стандартный вывод echo test > out.txt
2 stderr Ошибки ls /nope 2> err.log
3+ Пользовательские Дополнительные потоки exec 3> log.txt

FD3 — дополнительный поток, создаваемый пользователем:

exec 3> process.log
echo "Начало выполнения" >&3
exec 3>&-

Шаг 9: Ловушки и обработка ошибок

set -e
set -u
set -x
set -o pipefail

trap 'echo Завершено' EXIT
trap 'echo Ошибка' ERR

Шаг 10: Управление заданиями

sleep 10 &
jobs
fg %1
bg %1
disown %1
kill %1

Пояснение: номера заданий и %1

sleep 60 &
jobs

Вывод:

[1]+  Running  sleep 60 &
  • [1] — номер задания
  • %1 — ссылка на задание №1
Символ Значение
%1 Задание №1
%+ Текущее задание
%- Предыдущее задание

Шаг 11: Зарезервированные команды

:
true
false
source ~/.bashrc
eval "echo executed"
{ echo A; echo B; }

Итог

Это руководство охватывает все специальные конструкции, переменные, расширения и управляющие элементы Bash. Понимание их позволяет точно анализировать и проектировать скрипты с высокой безопасностью и повторным использованием.