Переменные в 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Изображение примера в терминале:

Посмотреть значение переменной можно через 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"Сделайте исполняемым и запустите с параметрами.

Переменные окружения
Переменные окружения (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 GeekBash воспримет 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) — как создать надёжный скрипт с переменными
- Начало: всегда указывайте shebang (#/bin/bash) и set -euo pipefail для строгого поведения.
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'- Опишите назначение скрипта в комментарии.
- Парсинг аргументов: проверьте $#, используйте getopts для флагов.
- Валидация: убедитесь, что входные пути и права доступа корректны.
- Используйте локальные переменные и явно экспортируйте только то, что нужно.
- Логирование: выводите понятные сообщения и коды возврата.
- Тестирование: пишите примеры запуска и проверяйте результаты.
Мини-образец шаблона скрипта:
#!/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):
- Логи не содержат секретных значений.
- Скрипт корректно возвращает коды ошибок.
- Метрики/триггеры при падении скрипта работают.
Критерии приёмки
- Скрипт корректно обрабатывает пустые и некорректные аргументы.
- Скрипт не изменяет глобальные переменные без экспорта и согласования.
- При запуске с тестовыми данными вывод соответствует ожидаемому.
- Скрипт имеет понятный код, комментарии и документацию по использованию.
Тестовые сценарии и случаи приёмки
- Запуск без аргументов — должен возвращать Usage и код 1.
- Запуск с несуществующей директорией — ошибка и код 2.
- Запуск с существующей директорией — вывод содержит корректное число файлов.
- Параллельный запуск скрипта не должен приводить к гонкам данных (если скрипт ничего не пишет в общие ресурсы).
Шпаргалка (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 в автоматизированных тестах, чтобы избежать неожиданных различий в выводе команд.
Примеры использования в реальных задачах
- Резервное копирование каталога с именем, содержащим пробелы.
backup_dir="$1"
if [ -z "${backup_dir:-}" ]; then
echo "Usage: $0 "
exit 1
fi
tar -czf "backup-$(date +%F).tar.gz" -C "$backup_dir" . - Параллельный запуск задач с уникальными TEMP-файлами:
task_id=$$
logfile="/var/log/mytask.$task_id.log"
command > "$logfile" 2>&1 &Конечное резюме
Переменные в Bash — основной инструмент для написания гибких и переиспользуемых скриптов. Освойте правила именования, работу с кавычками, специальные переменные и экспорт. Используйте шаблоны, чек-листы и тесты, чтобы держать скрипты безопасными и предсказуемыми.
Важно: всегда проверяйте внешние входы и избавляйтесь от хранения секретов в открытом виде.
Ссылка на иллюстрацию использования echo и отладки:

Похожие материалы
Очистка кэша в Windows 11 — полное руководство
Steam Remote Play не работает в Windows — как исправить
Как обновить Google Chrome на Ubuntu
Укачивание в играх: как остановить
Как вернуть меню Пуск Windows 10 в Windows 11