Гид по технологиям

Переменные в Bash: полное руководство

10 min read Bash Обновлено 26 Dec 2025
Переменные в Bash — полное руководство
Переменные в Bash — полное руководство

Переменные в Bash — это имена, которые хранят строки или числа и подставляются в команды при обращении через $. Они делают скрипты гибкими: можно принимать параметры, читать среду, экспортировать значения в дочерние процессы и безопасно обрабатывать значения с пробелами через кавычки. В руководстве объяснены правила именования, специальные переменные, экспорт, кавычки, отладка и лучшие практики, а также приведены чек-листы, шаблоны и тесты приёмки.

Быстрые ссылки

  • Что такое переменная в Bash?
  • Примеры переменных в Bash
  • Как использовать переменные в скриптах
  • Как передавать параметры командной строки в скриптах
  • Работа со специальными переменными
  • Переменные окружения
  • Как экспортировать переменные
  • Как правильно кавычить переменные
  • echo — ваш помощник

Краткое содержание

  • Переменная — это именованная ссылка на значение (строка или число).
  • Имена не должны начинаться с цифры и не содержать пробелов; разрешены буквы латинского алфавита, цифры и подчеркивание.
  • Для подстановки значения используйте $NAME или ${NAME}.
  • Для передачи аргументов используются $1..$9, $@, $#, $0 и другие.
  • Экспорт переменной делает её доступной дочерним процессам.
  • Оборачивайте значения в двойные кавычки для сохранения пробелов и специальных символов.

Важно: перед изменением скопированных скриптов из интернета сначала прогоняйте команды через echo и просмотрите код — это снижает риск нежелательных действий.

Что такое переменная в Bash?

Переменная в Bash — это имя, которому присвоено значение: строка или число. При выполнении команд Bash подставляет вместо имени само значение переменной.

Ключевые правила по именованию:

  • Имя не должно начинаться с цифры.
  • Имя не должно содержать пробелов.
  • Разрешены буквы (A–Z, a–z), цифры и подчеркивание (_).
  • Регистр имеет значение: myVar и myvar — разные переменные.

Краткое определение: переменная — это контейнер для текста или числа, доступный по имени.

Примеры переменных в Bash

Ниже создаём пять переменных. Формат: имя=значение без пробелов вокруг =. Это присваивание.

my_name=Dave
my_boost=Linux
him=Popeye
his_boost=Spinach
this_year=2019

Изображение примера в терминале:

Терминал Linux с примером определения переменных и вывода через echo

Посмотреть значение переменной можно через echo с префиксом $:

echo $my_name
echo $my_boost
echo $this_year

Использование всех переменных вместе:

echo "$my_boost is to $me as $his_boost is to $him (c) $this_year"

Подстановка значений заменит имена переменных на их содержимое.

Изменение значения переменной — простое повторное присваивание:

my_boost=Tequila

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

Важно запомнить:

  • Строки в одинарных кавычках ‘ ‘ считаются литералами: переменные в них не разворачиваются.
  • Строки в двойных кавычках “ “ разворачиваются: переменные подставляются.
  • Без $ вы получите имя переменной, а не её значение.

Примеры корректного и некорректного обращения к переменным в терминале

Создание переменной из других переменных:

drink_of_the_Year="$my_boost $this_year"

echo "$drink_of_the_Year"

Примечание: я заменил дефисы и подчеркивание в названиях переменных так, чтобы они соответствовали общепринятым правилам именования (не использовать дефис внутри имени переменной).

Как использовать переменные в скриптах

Переменные делают скрипт переносимым и универсальным. Пример: скрипт считает количество файлов в каталоге.

Создайте файл fcnt.sh с содержимым:

#!/bin/bash

folder_to_count=/dev
file_count=$(ls "$folder_to_count" | wc -l)

echo "$file_count files in $folder_to_count"

Сделайте файл исполняемым:

chmod +x fcnt.sh

Запустите:

./fcnt.sh

Как это работает:

  • folder_to_count содержит строку “/dev”.
  • file_count получает значение через командную подстановку $( ). Внутри выполняется ls на папке и подсчёт строк wc -l.
  • echo выводит готовый результат.

Теперь сделаем скрипт универсальным, чтобы он принимал аргумент (путь к папке).

Как передавать параметры командной строки в скриптах

Многие команды принимают параметры: ls, wc и другие. Скрипты тоже получают параметры: $1 — первый аргумент, $2 — второй и т.д. $0 — имя скрипта.

Пример, сохраняем как fcnt2.sh:

#!/bin/bash

folder_to_count=$1
file_count=$(ls "$folder_to_count" | wc -l)

echo "$file_count files in $folder_to_count"

Сделайте исполняемым и запустите с разными аргументами:

chmod +x fcnt2.sh
./fcnt2.sh /dev
./fcnt2.sh /etc
./fcnt2.sh /bin

Вы также можете не создавать промежуточную переменную и ссылаться на $1 напрямую:

#!/bin/bash

file_count=$(ls "$1" | wc -l)

echo "$file_count files in $1"

Совет: проверяйте, что $1 непустой, прежде чем использовать его. Это уменьшит количество ошибок.

if [ -z "$1" ]; then
  echo "Usage: $0 "
  exit 1
fi

Работа со специальными переменными

Bash предоставляет ряд предопределённых переменных, которые полезны при написании скриптов:

  • $# — количество переданных параметров.
  • $@ — все параметры в виде списка (каждый — отдельный элемент).
  • $? — код возврата последней выполненной команды.
  • $$ — PID текущего скрипта.
  • $USER — имя пользователя, запускающего скрипт.
  • $HOSTNAME — имя хоста.
  • $SECONDS — количество секунд с момента запуска оболочки/скрипта.
  • $RANDOM — псевдослучайное число от 0 до 32767.
  • $LINENO — текущий номер строки в скрипте.

Пример скрипта special.sh:

#!/bin/bash

echo "There were $# command line parameters"
echo "They are: $@"
echo "Parameter 1 is: $1"
echo "The script is called: $0"

# любой процесс, чтобы отследить код возврата
pwd

echo "pwd returned $?"

echo "This script has Process ID $$"
echo "The script was started by $USER"
echo "It is running on $HOSTNAME"
sleep 3

echo "It has been running for $SECONDS seconds"
echo "Random number: $RANDOM"
echo "This is line number $LINENO of the script"

Сделайте исполняемым и запустите с параметрами.

Запуск special.sh с набором аргументов в терминале

Переменные окружения

Переменные окружения (environment variables) используются Bash и другими программами для хранения настроек среды: HOME, LANG, PATH и т.д.

Посмотреть текущие переменные окружения:

env | less

Многие утилиты и скрипты ориентируются на переменные окружения. Например:

  • EDITOR или VISUAL — предпочитаемый редактор.
  • PATH — пути поиска исполняемых файлов.
  • LANG, LC_ALL — настройки локали.

Как экспортировать переменные

Без экспорта переменная доступна только в текущем процессе. Экспортированная переменная доступна дочерним процессам.

Пример взаимодействия двух скриптов.

script_one.sh:

#!/bin/bash

first_var=alpha
second_var=bravo

echo "$0: first_var=$first_var, second_var=$second_var"

export first_var
# second_var остаётся не экспортированной

./script_two.sh

echo "$0: first_var=$first_var, second_var=$second_var"

script_two.sh:

#!/bin/bash

echo "$0: first_var=$first_var, second_var=$second_var"

# пробуем изменить
first_var=charlie
second_var=delta

echo "$0: first_var=$first_var, second_var=$second_var"

Поведение:

  • script_one.sh показывает alpha и bravo.
  • script_two.sh получает значение first_var (alpha), но second_var пустой (не экспортирован).
  • Изменение first_var в дочернем процессе не меняет значение в родительском.

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

Как правильно кавычить переменные

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

Плохой пример:

site_name=How-To Geek

Bash воспримет How-To как часть команды, а не как единое значение — возникнет ошибка.

Хороший пример:

site_name="How-To Geek"
echo "$site_name"

Правила:

  • Оборачивайте значения в двойные кавычки при присваивании, если есть пробелы.
  • Используйте двойные кавычки при подстановке: echo “$var”.
  • Одинарные кавычки предотвращают подстановку переменных: echo ‘$var’ выведет буквальный $var.
  • Если нужно выполнить подстановку внутри строки, используйте двойные кавычки.

echo — ваш помощник при отладке

Перед выполнением команд вставьте echo для безопасной проверки того, что будет выполнено:

# вместо
rm -rf "$TARGET_DIR"

# сначала
echo rm -rf "$TARGET_DIR"

Это особенно важно при работе со скопированными скриптами.

Частые ошибки и как их избегать

  • Пробелы вокруг =: myvar = value — неверно. Правильно: myvar=value.
  • Использование дефиса в имени переменной: my-var — это минус, а не имя.
  • Неэкранированные пробелы в значении: site_name=How To Geek — Bash увидит несколько аргументов.
  • Ожидание изменений экспортированной переменной из дочернего процесса — изменения не приходят обратно.
  • Непроверенные аргументы: использование $1 без проверки может привести к ошибкам.

Безопасность и приватность

  • Никогда не храните секреты в открытых скриптах без шифрования.
  • Для секретов используйте специальные менеджеры (vault, pass) или минимизируйте экспорт секретов в окружение.
  • При логировании избегайте вывода значений секретных переменных.

Практическое руководство (SOP) — как создать надёжный скрипт с переменными

  1. Начало: всегда указывайте shebang (#/bin/bash) и set -euo pipefail для строгого поведения.
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
  1. Опишите назначение скрипта в комментарии.
  2. Парсинг аргументов: проверьте $#, используйте getopts для флагов.
  3. Валидация: убедитесь, что входные пути и права доступа корректны.
  4. Используйте локальные переменные и явно экспортируйте только то, что нужно.
  5. Логирование: выводите понятные сообщения и коды возврата.
  6. Тестирование: пишите примеры запуска и проверяйте результаты.

Мини-образец шаблона скрипта:

#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

# Описание: скрипт считает файлы в директории

usage() {
  echo "Usage: $0 [-h] "
  exit 1
}

if [ "${1:-}" = "-h" ]; then
  usage
fi

if [ -z "${1:-}" ]; then
  usage
fi

DIR="$1"
if [ ! -d "$DIR" ]; then
  echo "Error: $DIR is not a directory"
  exit 2
fi

count=$(ls "$DIR" | wc -l)

echo "$count files in $DIR"

Чек-лист по ролям

Разработчик:

  • Использовать set -euo pipefail.
  • Проверять входные аргументы.
  • Документировать переменные, которые экспортируются.
  • Не хранить секреты в скриптах.

Системный администратор:

  • Проверить права на скрипты (chmod).
  • Запускать тесты в изолированной среде.
  • Проверить совместимость с /bin/bash на целевой системе.

Оператор (SRE):

  • Логи не содержат секретных значений.
  • Скрипт корректно возвращает коды ошибок.
  • Метрики/триггеры при падении скрипта работают.

Критерии приёмки

  • Скрипт корректно обрабатывает пустые и некорректные аргументы.
  • Скрипт не изменяет глобальные переменные без экспорта и согласования.
  • При запуске с тестовыми данными вывод соответствует ожидаемому.
  • Скрипт имеет понятный код, комментарии и документацию по использованию.

Тестовые сценарии и случаи приёмки

  1. Запуск без аргументов — должен возвращать Usage и код 1.
  2. Запуск с несуществующей директорией — ошибка и код 2.
  3. Запуск с существующей директорией — вывод содержит корректное число файлов.
  4. Параллельный запуск скрипта не должен приводить к гонкам данных (если скрипт ничего не пишет в общие ресурсы).

Шпаргалка (Cheat sheet)

  • Присваивание: NAME=value
  • Подстановка: $NAME или ${NAME}
  • Командная подстановка: $(command)
  • Экспорт: export NAME
  • Проверка пустоты: [ -z “${VAR:-}” ]
  • Проверка существования файла: [ -f “$FILE” ]
  • Проверка директории: [ -d “$DIR” ]

Полезные конструкции:

# default if empty
: ${VAR:=default}

# read from stdin with fallback
read -r VAR < <(command || echo "default")

Альтернативные подходы

  • Вместо большого числа переменных в скрипте используйте конфигурационный файл в формате key=value и source его. Учтите риск выполнения непроверенного кода при source.
  • Для секретов используйте специализированные хранилища (vault, HashiCorp Vault, AWS Secrets Manager) вместо переменных окружения.
  • Для сложной логики рассмотрите перевод на более мощный язык (Python, Perl) и использование модульных библиотек.

Когда подход с переменными в Bash подводит

  • Очень сложная обработка JSON или структурированных данных — лучше использовать jq или перейти на Python.
  • Параллелизм и конкурентный доступ к общим ресурсам требуют дополнительной синхронизации.
  • Требования к строгой типизации и математике (большие числа, точность) лучше решать вне Bash.

Ментальные модели и эвристики

  • Модель “контейнер“: переменная — это контейнер, который хранит строку. Всегда думайте о ней как о тексте.
  • Эвристика “проверяй входы”: любой внешний ввод (аргументы, файлы, stdin, env) проверяйте.
  • Подстановка с кавычками — правило по умолчанию: всегда используйте двойные кавычки.

Таблица полезных команд Linux

| | Команды Linux | | Files | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc · tr | | | Processes | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap | | | Networking | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld |

Факто-бокс: ключевые правила

  • Имена: буквы, цифры, подчеркивание; не начинать с цифры.
  • Подстановка: всегда используйте $ or ${}.
  • Кавычки: двойные для подстановки, одинарные для литералов.
  • Экспорт: делает переменные видимыми для дочерних процессов, изменения в дочерних не возвращаются.

Примеры шаблонов и сниппетов

Проверка и дефолт:

: ${VAR:="default"}

Цикл по аргументам:

for arg in "$@"; do
  echo "Processing $arg"
done

Безопасное временное имя файла:

tmpfile=$(mktemp /tmp/myapp.XXXXXX)
trap 'rm -f "$tmpfile"' EXIT

Диагностика и отладка

  • set -x — включает трассировку выполнения (печатает команды с подставленными значениями).
  • set +x — отключает трассировку.
  • Используйте echo и printf для проверки промежуточных значений.

Пример включения отладки для части скрипта:

if [ "${DEBUG:-}" = "1" ]; then
  set -x
fi

# ...код...

set +x

Решение проблем на диаграмме

flowchart TD
  A[Есть аргументы?] -->|нет| B[Показать usage и выйти]
  A -->|да| C[Проверить, что путь существует]
  C -->|нет| D[Ошибка: нет директории]
  C -->|да| E[Выполнить подсчёт файлов]
  E --> F[Вывести результат]

Локализация и особенности целевой системы

  • В русскоязычной среде переменные окружения и локаль (LANG, LC_ALL) могут менять поведение команд, особенно при сортировке и обработке дат.
  • Проверяйте LC_ALL и LANG в автоматизированных тестах, чтобы избежать неожиданных различий в выводе команд.

Примеры использования в реальных задачах

  1. Резервное копирование каталога с именем, содержащим пробелы.
backup_dir="$1"
if [ -z "${backup_dir:-}" ]; then
  echo "Usage: $0 "
  exit 1
fi

tar -czf "backup-$(date +%F).tar.gz" -C "$backup_dir" .
  1. Параллельный запуск задач с уникальными TEMP-файлами:
task_id=$$
logfile="/var/log/mytask.$task_id.log"
command > "$logfile" 2>&1 &

Конечное резюме

Переменные в Bash — основной инструмент для написания гибких и переиспользуемых скриптов. Освойте правила именования, работу с кавычками, специальные переменные и экспорт. Используйте шаблоны, чек-листы и тесты, чтобы держать скрипты безопасными и предсказуемыми.

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

Ссылка на иллюстрацию использования echo и отладки:

Вывод команд echo и отладочная трассировка в терминале

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Очистка кэша в Windows 11 — полное руководство
Windows

Очистка кэша в Windows 11 — полное руководство

Steam Remote Play не работает в Windows — как исправить
Техподдержка

Steam Remote Play не работает в Windows — как исправить

Как обновить Google Chrome на Ubuntu
Ubuntu

Как обновить Google Chrome на Ubuntu

Укачивание в играх: как остановить
Игры

Укачивание в играх: как остановить

Как вернуть меню Пуск Windows 10 в Windows 11
Windows

Как вернуть меню Пуск Windows 10 в Windows 11

Помощь по командам в терминале Linux
Linux

Помощь по командам в терминале Linux