09. Bash-скрипти¶
Довідник бонус-уроку «Linux для розробника»
Розділ перевірено: кожну команду виконано в контейнерах Ubuntu, Debian і python:3.12-slim. Урок з вправами — Бонус. Linux.
Навіщо це потрібно¶
Уяви, що кожен раз при деплої ти вводиш 15 команд вручну: git pull, source .venv/bin/activate, pip install -r requirements.txt, python manage.py migrate, python manage.py collectstatic, sudo systemctl restart myapp... Це повільно і ти неодмінно щось пропустиш або наберешь помилку.
Bash-скрипт — це файл, де записані всі ці команди по порядку. Запускаєш один файл — він все робить сам.
Просте пояснення¶
Bash-скрипт — це список команд, записаних у файл. Замість того щоб вводити їх вручну одну за одною — ти запускаєш один файл і він все робить за тебе.
Shebang — перший рядок скрипта¶
Перший рядок скрипта завжди починається з #! (shebang). Він вказує, якою програмою виконувати файл.
/usr/bin/env bash — знайти bash через env (надійніший варіант, ніж #!/bin/bash, бо bash може бути в різних місцях).
Перший скрипт¶
#!/usr/bin/env bash
echo "Починаємо налаштування Django проєкту..."
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py collectstatic --noinput
echo "Готово!"
Зберегти у файл setup.sh, зробити виконуваним і запустити:
Змінні¶
#!/usr/bin/env bash
PROJECT_DIR="/var/www/myapp"
VENV_DIR="$PROJECT_DIR/.venv"
APP_USER="www-data"
echo "Проєкт: $PROJECT_DIR"
echo "Virtualenv: $VENV_DIR"
Правила змінних у Bash:
- Без пробілів: NAME="value" ✓, NAME = "value" ✗
- Читати через $: $NAME або ${NAME}
- Лапки важливі: "$NAME" збереже пробіли
Умови (if/else)¶
#!/usr/bin/env bash
if [ -f ".env" ]; then
echo ".env файл знайдено"
else
echo "ПОМИЛКА: .env файл відсутній"
exit 1
fi
Корисні перевірки:
| Умова | Що перевіряє |
|---|---|
[ -f file ] |
файл існує |
[ -d dir ] |
директорія існує |
[ -z "$VAR" ] |
змінна порожня |
[ "$A" = "$B" ] |
рядки рівні |
[ $N -gt 0 ] |
число більше за 0 |
Exit codes у скриптах¶
#!/usr/bin/env bash
# Зупинитися при першій помилці
set -e
git pull origin main
source .venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
echo "Деплой успішний!"
set -e — дуже корисна опція: якщо будь-яка команда повернула ненульовий exit code — скрипт зупиниться. Без цього скрипт продовжить виконання навіть після помилки.
Винятки:
set -eне спрацює на команді в умовіif, ліворуч від&&/||і на будь-якій, крім останньої, команді конвеєраa | b. Тому в скриптах деплою часто пишутьset -euo pipefail:-u— помилка при зверненні до незаданої змінної,-o pipefail— конвеєр падає, якщо впала будь-яка його команда.
Цикли¶
#!/usr/bin/env bash
# Виконати команду для кожного аргументу
for app in users notes tags; do
echo "Запускаємо міграції для $app..."
python manage.py migrate $app
done
# Перебрати файли
for file in *.py; do
echo "Файл: $file"
done
Аргументи командного рядка¶
#!/usr/bin/env bash
ENVIRONMENT=${1:-development} # $1 — перший аргумент, за замовчуванням development
echo "Деплой у середовище: $ENVIRONMENT"
if [ "$ENVIRONMENT" = "production" ]; then
echo "Увага: деплой на production!"
fi
Запуск:
Реальний скрипт деплою¶
#!/usr/bin/env bash
set -e
echo "=== Деплой Django-проєкту ==="
# Змінні
APP_DIR="/var/www/myapp"
VENV="$APP_DIR/.venv"
SERVICE_NAME="myapp"
# Оновити код
cd "$APP_DIR"
git pull origin main
# Оновити залежності
source "$VENV/bin/activate"
pip install -r requirements.txt --quiet
# Застосувати міграції
python manage.py migrate --noinput
# Зібрати статику
python manage.py collectstatic --noinput
# Перезапустити сервіс
sudo systemctl restart "$SERVICE_NAME"
echo "=== Деплой завершено! ==="
echo "Статус сервісу:"
systemctl status "$SERVICE_NAME" --no-pager
Debugging скрипта¶
bash -x script.sh # виконати з трасуванням (показує кожну команду)
set -x # увімкнути трасування всередині скрипта
set +x # вимкнути трасування
Типові помилки початківців¶
Помилка 1: Permission denied при запуску скрипта
Забув
chmod +x script.sh
Помилка 2: /usr/bin/env: 'bash\r': No such file or directory або script.sh: line 2: $'\r': command not found
Файл збережений у Windows-форматі (CRLF). Виправ:
sed -i 's/\r//' script.sh
Помилка 3: Скрипт продовжується після помилки і ламає сервер
Додай
set -eна початку скрипта
Помилка 4: Пробіли навколо = у змінних
NAME="value"✓,NAME = "value"✗ — Bash сприймеNAMEяк команду
Практичне завдання¶
Завдання 1¶
Напиши setup.sh для Django-проєкту:
1. Перевіряє наявність .env
2. Створює virtualenv (якщо не існує)
3. Встановлює залежності
4. Виконує міграції
Завдання 2¶
Напиши deploy.sh:
1. git pull
2. pip install -r requirements.txt
3. python manage.py migrate
4. python manage.py collectstatic --noinput
5. Перевіряє exit code кожного кроку
Завдання 3¶
Запусти скрипт з трасуванням і проаналізуй вивід.Самоперевірка¶
- [ ] Я розумію, що таке shebang і навіщо він потрібен
- [ ] Я можу написати скрипт з змінними, умовами і циклами
- [ ] Я знаю, що
set -eзупиняє скрипт при помилці - [ ] Я вмію зробити скрипт виконуваним через
chmod +x - [ ] Я можу написати простий деплой-скрипт для Django
Короткий підсумок¶
Bash-скрипт — набір команд у файлі. Shebang вказує інтерпретатор. set -e — зупинка при помилці. Реальний деплой починається з написання скрипта, який автоматизує всі ручні кроки. Наступний крок — Makefile, ще один спосіб організувати команди.