Bash-скрипты для автоматизации рутины: пишем с нуля
Практическое руководство по Bash-скриптам: от структуры и защитных флагов до бэкапа папки и запуска через cron.
Любую рутину, которую вы повторяете в терминале руками, можно превратить в скрипт и забыть о ней. Bash-скрипты - это простой способ автоматизировать бэкапы, чистку логов, обработку файлов и запускать всё это по расписанию. В этой статье соберём практическую базу: от структуры скрипта до реальных примеров, которые можно поставить на cron уже сегодня.
Структура надёжного скрипта
Любой скрипт начинается с шебанга - строки, которая говорит системе, чем его выполнять. Рекомендую использовать вариант через env: он находит bash в PATH и работает на большинстве систем.
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'Строка set -euo pipefail - это защита от тихих ошибок, и её стоит ставить почти всегда. Разберём флаги: -e прерывает скрипт при первой же ошибке команды; -u запрещает использование необъявленных переменных (частый источник багов); -o pipefail ловит ошибку в любой части конвейера, а не только в последней. Без этих флагов скрипт может продолжать работать после сбоя и наделать бед.
Не забудьте сделать файл исполняемым.
chmod +x myscript.sh
./myscript.shПеременные и аргументы
Переменные в Bash объявляются без пробелов вокруг знака равно. Обращение к значению - через $, и хорошая привычка всегда брать значения в двойные кавычки, чтобы пробелы в путях не ломали логику.
name="backup"
target_dir="/var/www"
date_stamp="$(date +%Y-%m-%d)"
echo "Запускаю $name для $target_dir на $date_stamp"Аргументы, переданные скрипту, доступны как $1, $2 и так далее; $# хранит их количество, а $@ - все сразу. Полезно проверять, что аргумент вообще передали.
if [ "$#" -lt 1 ]; then
echo "Использование: $0 <путь>" >&2
exit 1
fi
source_path="$1"Условия и циклы
Условия проверяют состояние: существует ли файл, равны ли значения, пуста ли строка. Циклы позволяют пройтись по списку файлов или строк.
# проверка существования каталога
if [ -d "$source_path" ]; then
echo "Каталог найден"
else
echo "Каталог не найден" >&2
exit 1
fi
# перебор всех .log файлов
for file in /var/log/myapp/*.log; do
echo "Обрабатываю $file"
doneОператор [ -d ] проверяет каталог, [ -f ] - обычный файл, [ -z ] - пустую строку. Перенаправление >&2 отправляет сообщение в поток ошибок, что правильно для диагностики.
Функции для повторяющейся логики
Когда один и тот же кусок кода встречается несколько раз, вынесите его в функцию. Это делает скрипт читаемым и упрощает поддержку. Удобно завести функцию логирования с меткой времени.
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
die() {
echo "ОШИБКА: $*" >&2
exit 1
}
log "Скрипт стартовал"Пример 1: бэкап папки
Соберём полноценный скрипт, который упаковывает каталог в архив с датой в имени и складывает его в папку бэкапов. Он проверяет вход, создаёт целевую папку и логирует результат.
#!/usr/bin/env bash
set -euo pipefail
src="${1:?Укажите папку для бэкапа}"
backup_dir="/backups"
stamp="$(date +%Y-%m-%d_%H%M%S)"
archive="$backup_dir/$(basename "$src")_$stamp.tar.gz"
log() { echo "[$(date '+%F %T')] $*"; }
[ -d "$src" ] || { echo "Нет папки: $src" >&2; exit 1; }
mkdir -p "$backup_dir"
log "Архивирую $src"
tar -czf "$archive" -C "$(dirname "$src")" "$(basename "$src")"
log "Готово: $archive"Конструкция ${1:?сообщение} завершит скрипт с внятной ошибкой, если аргумент не передан - удобная защита в одну строку.
Пример 2: чистка старых логов
Второй частый сценарий - удаление логов старше N дней, чтобы диск не забивался. Здесь помогает утилита find.
#!/usr/bin/env bash
set -euo pipefail
log_dir="/var/log/myapp"
days=14
# найти и удалить .log старше 14 дней
find "$log_dir" -type f -name "*.log" -mtime +"$days" -print -deleteФлаг -mtime +14 отбирает файлы, изменённые более 14 дней назад, -print покажет их имена, а -delete удалит. Перед первым запуском уберите -delete, чтобы просто посмотреть список кандидатов - так безопаснее.
Запуск по расписанию через cron
Чтобы скрипт работал сам, добавьте его в crontab - планировщик задач. Откройте редактор расписания командой crontab -e и добавьте строку. Формат: минута, час, день месяца, месяц, день недели, затем команда.
# бэкап /var/www каждый день в 3:30 ночи
30 3 * * * /home/user/backup.sh /var/www >> /var/log/backup.log 2>&1
# чистка логов по понедельникам в 4:00
0 4 * * 1 /home/user/clean-logs.shКонструкция >> файл 2>&1 сохраняет весь вывод и ошибки в лог - это очень важно, ведь при запуске из cron вы не видите терминал. Указывайте в crontab полные пути и к скрипту, и к файлам внутри него: у cron минимальное окружение, и относительные пути часто не работают.
Совет: перед постановкой на cron всегда запустите скрипт руками и проверьте, что он корректно завершается и пишет понятный лог. Автоматизация хороша только тогда, когда ей можно доверять.
С этой базой вы уже можете автоматизировать большую часть повседневной рутины. Начните с малого - оберните в скрипт одну надоевшую команду, добавьте защитные флаги и логирование, а затем поставьте на расписание.