Промпт: скрипт для автоматизации
Bash или PowerShell скрипт с проверками и логом. Готовый промт на русском: скопируйте, подставьте свои данные и вставьте в GigaChat, YandexGPT, ChatGPT, Claude или Gemini.
Текст промпта
Что подставить в промт
| Поле | Пример |
|---|---|
| {shell} | bash |
| {task} | каждую ночь архивировать папку /var/www/site/uploads в /backup с датой в имени и удалять архивы старше 14 дней |
| {scheduler} | cron |
Ответы нейросетей на этот промпт
Скрипт на Bash
Вот готовый пример скрипта archive_and_cleanup.sh, который соответствует указанным требованиям:
#!/bin/bash
# Имя файла журнала
LOG_FILE="/var/log/archive.log"
# Папка исходной директории
SOURCE_DIR="/var/www/site/uploads"
# Директория назначения резервных копий
BACKUP_DIR="/backup"
# Флаг удаления старых файлов (-d)
DELETE_OLD=0
# Функция вывода сообщений в журнал
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') $*" >> "${LOG_FILE}"
}
# Проверяем наличие tar
if ! command -v tar &> /dev/null; then
log "Ошибка: программа 'tar' отсутствует."
exit 1
fi
# Проверяем наличие find
if ! command -v find &> /dev/null; then
log "Ошибка: программа 'find' отсутствует."
exit 1
fi
# Опция '-d': удалить старые файлы
while getopts ":d" opt; do
case ${opt} in
d ) DELETE_OLD=1;;
\? )
log "Неизвестный параметр: $-OPTARG"
exit 1
;;
esac
done
# Проверяем существование каталога исходника
if [ ! -d "${SOURCE_DIR}" ]; then
log "Ошибка: каталог '${SOURCE_DIR}' не существует!"
exit 1
fi
# Создаем директорию backup, если её ещё нет
mkdir -p "${BACKUP_DIR}"
# Архивируем папку с текущей датой
TODAY=$(date +"%Y%m%d")
ARCHIVE_NAME="uploads-${TODAY}.tar.gz"
# Формирование полного пути до нового архива
FULL_ARCHIVE_PATH="${BACKUP_DIR}/${ARCHIVE_NAME}"
# Создание архива
if tar czf "${FULL_ARCHIVE_PATH}" "${SOURCE_DIR}" >& /dev/null; then
log "Архив успешно создан: ${FULL_ARCHIVE_PATH}"
else
log "Ошибка при создании архива: ${FULL_ARCHIVE_PATH}"
exit 1
fi
# Удаление архивов старше 14 дней (только если установлен флаг "-d")
if [[ ${DELETE_OLD} == 1 ]]; then
OLD_FILES=$(find "${BACKUP_DIR}" -name "uploads-*.tar.gz" -type f -mtime +14)
if [[ -n "${OLD_FILES}" ]]; then
for file in ${OLD_FILES}; do
rm -f "${file}"
log "Удалён старый архив: ${file}"
done
fi
else
log "Флаг удаления старых архивов отключён."
fi
exit 0
Как использовать этот скрипт?
Шаг 1: Сохраните скрипт
Сохраните приведённый выше код в файле, например /usr/local/bin/archive_and_cleanup.sh.
Шаг 2: Сделайте исполняемым
Установите права на выполнение:
chmod +x /usr/local/bin/archive_and_cleanup.sh
Шаг 3: Тестовый запуск вручную
Перед настройкой cron убедитесь, что всё работает корректно:
sudo ./archive_and_cleanup.sh
Проверьте логи (cat /var/log/archive.log) и убедитесь, что ошибок нет.
Шаг 4: Автоматический запуск через Cron
Добавьте задание в crontab для ежедневного запуска ночью, например в полночь:
crontab -e
Добавьте строку:
0 0 * * * /usr/local/bin/archive_and_cleanup.sh
Эта команда будет запускаться каждый день ровно в полночь.
Дополнительная настройка (при необходимости удаления старых архивов):
Чтобы включить удаление старых архивов старше 14 дней, добавьте ключ -d:
0 0 * * * /usr/local/bin/archive_and_cleanup.sh -d
Таким образом, скрипт автоматически выполнит свою работу, включая создание новых архивов и очистку старых — безопасно и предсказуемо!
#!/usr/bin/env bash
#
# backup_uploads.sh
#
# Архивирует папку /var/www/site/uploads в /backup с датой в имени.
# Архивы старше N дней удаляются только при явном флаге --prune.
#
# Пример архива:
# /backup/uploads_2026-10-01_02-30-00.tar.gz
set -Eeuo pipefail
# -----------------------------
# Настройки по умолчанию
# -----------------------------
SOURCE_DIR="/var/www/site/uploads"
BACKUP_DIR="/backup"
RETENTION_DAYS=14
LOG_FILE="/var/log/backup_uploads.log"
# Удаление старых архивов по умолчанию отключено.
# Чтобы включить, нужно явно передать флаг --prune.
PRUNE_OLD_BACKUPS=0
# -----------------------------
# Функции
# -----------------------------
usage() {
cat <<EOF
Использование:
$0 [--source DIR] [--dest DIR] [--retention DAYS] [--log FILE] [--prune]
Параметры:
--source DIR Папка для архивирования.
По умолчанию: ${SOURCE_DIR}
--dest DIR Папка, куда сохранять архивы.
По умолчанию: ${BACKUP_DIR}
--retention DAYS Сколько дней хранить архивы.
По умолчанию: ${RETENTION_DAYS}
--log FILE Файл лога.
По умолчанию: ${LOG_FILE}
--prune Явно разрешить удаление архивов старше retention дней.
-h, --help Показать эту справку.
Примеры:
$0
$0 --prune
$0 --source /var/www/site/uploads --dest /backup --retention 14 --prune
EOF
}
log() {
local level="$1"
shift
local message="$*"
local timestamp
timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}
die() {
log "ERROR" "$*"
exit 1
}
check_command() {
local cmd="$1"
if ! command -v "$cmd" >/dev/null 2>&1; then
die "Не найдена необходимая программа: $cmd"
fi
}
is_positive_integer() {
[[ "$1" =~ ^[0-9]+$ ]] && [[ "$1" -gt 0 ]]
}
# -----------------------------
# Разбор аргументов
# -----------------------------
while [[ $# -gt 0 ]]; do
case "$1" in
--source)
[[ $# -ge 2 ]] || {
echo "Ошибка: для --source нужно указать путь" >&2
exit 1
}
SOURCE_DIR="$2"
shift 2
;;
--dest)
[[ $# -ge 2 ]] || {
echo "Ошибка: для --dest нужно указать путь" >&2
exit 1
}
BACKUP_DIR="$2"
shift 2
;;
--retention)
[[ $# -ge 2 ]] || {
echo "Ошибка: для --retention нужно указать количество дней" >&2
exit 1
}
RETENTION_DAYS="$2"
shift 2
;;
--log)
[[ $# -ge 2 ]] || {
echo "Ошибка: для --log нужно указать путь к файлу лога" >&2
exit 1
}
LOG_FILE="$2"
shift 2
;;
--prune)
PRUNE_OLD_BACKUPS=1
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Ошибка: неизвестный параметр: $1" >&2
usage
exit 1
;;
esac
done
# -----------------------------
# Проверки
# -----------------------------
# Проверка нужных программ.
check_command "tar"
check_command "gzip"
check_command "find"
check_command "date"
check_command "mkdir"
check_command "tee"
# Проверка retention.
if ! is_positive_integer "$RETENTION_DAYS"; then
die "RETENTION_DAYS должен быть положительным целым числом. Получено: $RETENTION_DAYS"
fi
# Проверка исходной директории.
if [[ ! -d "$SOURCE_DIR" ]]; then
die "Исходная папка не существует или не является директорией: $SOURCE_DIR"
fi
if [[ ! -r "$SOURCE_DIR" ]]; then
die "Нет прав на чтение исходной папки: $SOURCE_DIR"
fi
# Создаём директорию для бэкапов, если её нет.
if [[ ! -d "$BACKUP_DIR" ]]; then
mkdir -p "$BACKUP_DIR" || die "Не удалось создать папку для бэкапов: $BACKUP_DIR"
fi
if [[ ! -d "$BACKUP_DIR" ]]; then
die "Путь для бэкапов не является директорией: $BACKUP_DIR"
fi
if [[ ! -w "$BACKUP_DIR" ]]; then
die "Нет прав на запись в папку бэкапов: $BACKUP_DIR"
fi
# Создаём папку для лога, если нужно.
LOG_DIR="$(dirname "$LOG_FILE")"
if [[ ! -d "$LOG_DIR" ]]; then
mkdir -p "$LOG_DIR" || {
echo "Ошибка: не удалось создать папку для лога: $LOG_DIR" >&2
exit 1
}
fi
if [[ ! -w "$LOG_DIR" ]]; then
echo "Ошибка: нет прав на запись в папку лога: $LOG_DIR" >&2
exit 1
fi
# -----------------------------
# Архивирование
# -----------------------------
DATE_SUFFIX="$(date '+%Y-%m-%d_%H-%M-%S')"
ARCHIVE_NAME="uploads_${DATE_SUFFIX}.tar.gz"
ARCHIVE_PATH="${BACKUP_DIR}/${ARCHIVE_NAME}"
log "INFO" "Начало резервного копирования"
log "INFO" "Источник: $SOURCE_DIR"
log "INFO" "Назначение: $ARCHIVE_PATH"
# Важно:
# tar -C позволяет не сохранять в архив абсолютные пути.
# В архив попадёт папка uploads, а не полный путь /var/www/site/uploads.
SOURCE_PARENT="$(dirname "$SOURCE_DIR")"
SOURCE_BASE="$(basename "$SOURCE_DIR")"
if tar -czf "$ARCHIVE_PATH" -C "$SOURCE_PARENT" "$SOURCE_BASE"; then
log "INFO" "Архив успешно создан: $ARCHIVE_PATH"
else
rm -f "$ARCHIVE_PATH"
die "Ошибка при создании архива. Неполный архив удалён: $ARCHIVE_PATH"
fi
# Проверка, что архив действительно создан и не пустой.
if [[ ! -s "$ARCHIVE_PATH" ]]; then
rm -f "$ARCHIVE_PATH"
die "Архив создан, но он пустой. Файл удалён: $ARCHIVE_PATH"
fi
# -----------------------------
# Удаление старых архивов
# -----------------------------
if [[ "$PRUNE_OLD_BACKUPS" -eq 1 ]]; then
log "INFO" "Включено удаление архивов старше ${RETENTION_DAYS} дней"
# Удаляются только файлы, подходящие под шаблон uploads_*.tar.gz
# и только внутри BACKUP_DIR.
#
# -mtime +14 означает: старше 14 полных суток.
#
# -print логирует каждый удаляемый файл.
find "$BACKUP_DIR" \
-maxdepth 1 \
-type f \
-name 'uploads_*.tar.gz' \
-mtime +"$RETENTION_DAYS" \
-print \
-delete | while IFS= read -r deleted_file; do
log "INFO" "Удалён старый архив: $deleted_file"
done
log "INFO" "Удаление старых архивов завершено"
else
log "INFO" "Удаление старых архивов отключено. Чтобы включить, запустите скрипт с флагом --prune"
fi
log "INFO" "Резервное копирование завершено успешно"
exit 0
Как сохранить скрипт
Например:
sudo nano /usr/local/sbin/backup_uploads.sh
Вставьте код, сохраните файл и сделайте его исполняемым:
sudo chmod 750 /usr/local/sbin/backup_uploads.sh
Если архивирование должен выполнять пользователь root, владельцем можно сделать root:
sudo chown root:root /usr/local/sbin/backup_uploads.sh
Как запустить вручную
Создать архив без удаления старых архивов:
sudo /usr/local/sbin/backup_uploads.sh
Создать архив и удалить архивы старше 14 дней:
sudo /usr/local/sbin/backup_uploads.sh --prune
Запуск с явным указанием всех параметров:
sudo /usr/local/sbin/backup_uploads.sh \
--source /var/www/site/uploads \
--dest /backup \
--retention 14 \
--log /var/log/backup_uploads.log \
--prune
Посмотреть лог:
sudo tail -f /var/log/backup_uploads.log
Как поставить в cron
Откройте crontab для root:
sudo crontab -e
Добавьте строку для запуска каждую ночь, например в 02:30:
30 2 * * * /usr/local/sbin/backup_uploads.sh --prune >/dev/null 2>&1
Здесь флаг --prune указан явно, поэтому старые архивы будут удаляться. Без этого флага скрипт будет только создавать новые архивы и ничего не удалять.
Проверить список заданий cron:
sudo crontab -l#!/usr/bin/env bash
#
# backup_uploads.sh — ночной бэкап /var/www/site/uploads в /backup
#
# Поведение:
# - создаёт архив вида uploads_YYYY-MM-DD_HH-MM-SS.tar.gz
# - пишет подробный лог в файл
# - НИЧЕГО не удаляет по умолчанию (safe by default)
# - удаление старых архивов происходит только с флагом --delete-old
#
# Использование:
# ./backup_uploads.sh # только бэкап
# ./backup_uploads.sh --delete-old # бэкап + удаление архивов старше N дней
# ./backup_uploads.sh --dry-run-delete # показать, что будет удалено, без удаления
#
# Коды возврата:
# 0 - успех
# 1 - ошибка конфигурации/окружения
# 2 - ошибка при создании архива
# 3 - ошибка при удалении старых архивов
set -o pipefail # не используем "set -e" целиком, т.к. хотим сами обрабатывать ошибки
# ---------------------------
# Настройки (можно вынести в отдельный конфиг-файл при желании)
# ---------------------------
SOURCE_DIR="/var/www/site/uploads"
BACKUP_DIR="/backup"
RETENTION_DAYS=14
LOG_FILE="/var/log/backup_uploads.log"
LOCK_FILE="/var/run/backup_uploads.lock"
ARCHIVE_PREFIX="uploads"
TIMESTAMP="$(date +%Y-%m-%d_%H-%M-%S)"
ARCHIVE_NAME="${ARCHIVE_PREFIX}_${TIMESTAMP}.tar.gz"
ARCHIVE_PATH="${BACKUP_DIR}/${ARCHIVE_NAME}"
# Флаги, управляющие поведением (безопасность по умолчанию)
DELETE_OLD=false
DRY_RUN_DELETE=false
# ---------------------------
# Разбор аргументов
# ---------------------------
usage() {
cat <<EOF
Использование: $(basename "$0") [опции]
Опции:
--delete-old Удалять архивы старше ${RETENTION_DAYS} дней после создания бэкапа
--dry-run-delete Показать, какие архивы были бы удалены, но ничего не удалять
-h, --help Показать эту справку
EOF
}
for arg in "$@"; do
case "$arg" in
--delete-old)
DELETE_OLD=true
;;
--dry-run-delete)
DRY_RUN_DELETE=true
;;
-h|--help)
usage
exit 0
;;
*)
echo "Неизвестный аргумент: $arg" >&2
usage
exit 1
;;
esac
done
# ---------------------------
# Функция логирования: пишет и в лог-файл, и в stdout
# ---------------------------
log() {
local level="$1"
shift
local msg="$*"
local line
line="[$(date '+%Y-%m-%d %H:%M:%S')] [${level}] ${msg}"
echo "$line" | tee -a "$LOG_FILE"
}
fail() {
log "ERROR" "$*"
exit "${2:-1}"
}
# ---------------------------
# Предварительные проверки
# ---------------------------
# Проверяем, что лог-файл доступен для записи (создаём при необходимости)
if ! touch "$LOG_FILE" 2>/dev/null; then
echo "Не удалось создать/открыть лог-файл: $LOG_FILE" >&2
exit 1
fi
log "INFO" "=== Запуск скрипта бэкапа ==="
# Проверка наличия обязательных программ
for cmd in tar find date df; do
if ! command -v "$cmd" >/dev/null 2>&1; then
fail "Требуемая программа '$cmd' не найдена в PATH" 1
fi
done
# Проверка существования исходной директории
if [[ ! -d "$SOURCE_DIR" ]]; then
fail "Исходная директория не существует: $SOURCE_DIR" 1
fi
if [[ ! -r "$SOURCE_DIR" ]]; then
fail "Нет прав на чтение исходной директории: $SOURCE_DIR" 1
fi
# Проверка/создание директории для бэкапов
if [[ ! -d "$BACKUP_DIR" ]]; then
log "INFO" "Директория бэкапов $BACKUP_DIR не найдена, пытаемся создать"
if ! mkdir -p "$BACKUP_DIR"; then
fail "Не удалось создать директорию бэкапов: $BACKUP_DIR" 1
fi
fi
if [[ ! -w "$BACKUP_DIR" ]]; then
fail "Нет прав на запись в директорию бэкапов: $BACKUP_DIR" 1
fi
# Проверка свободного места (минимум требуем хотя бы 100 МБ свободно, можно скорректировать)
MIN_FREE_KB=102400
AVAILABLE_KB=$(df --output=avail "$BACKUP_DIR" | tail -n1 | tr -d ' ')
if [[ "$AVAILABLE_KB" -lt "$MIN_FREE_KB" ]]; then
fail "Недостаточно свободного места в $BACKUP_DIR (доступно: ${AVAILABLE_KB}KB)" 1
fi
# ---------------------------
# Блокировка на случай параллельного запуска
# ---------------------------
exec 200>"$LOCK_FILE"
if ! flock -n 200; then
fail "Другой экземпляр скрипта уже выполняется (lock: $LOCK_FILE)" 1
fi
# ---------------------------
# Создание архива
# ---------------------------
log "INFO" "Создаём архив: $ARCHIVE_PATH"
# Архивируем, сохраняя относительные пути (без ведущего /)
if tar -czf "$ARCHIVE_PATH" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")" 2>>"$LOG_FILE"; then
log "INFO" "Архив успешно создан: $ARCHIVE_PATH ($(du -h "$ARCHIVE_PATH" | cut -f1))"
else
# Удаляем недобитый/битый архив, если он создался
[[ -f "$ARCHIVE_PATH" ]] && rm -f "$ARCHIVE_PATH"
fail "Ошибка при создании архива. Подробности в $LOG_FILE" 2
fi
# ---------------------------
# Удаление старых архивов (только если явно разрешено)
# ---------------------------
if $DELETE_OLD || $DRY_RUN_DELETE; then
log "INFO" "Поиск архивов старше ${RETENTION_DAYS} дней для удаления"
# Ищем только файлы с нашим префиксом и расширением, чтобы не задеть чужие файлы
mapfile -t OLD_FILES < <(find "$BACKUP_DIR" -maxdepth 1 -type f \
-name "${ARCHIVE_PREFIX}_*.tar.gz" -mtime +"$RETENTION_DAYS")
if [[ ${#OLD_FILES[@]} -eq 0 ]]; then
log "INFO" "Старых архивов для удаления не найдено"
else
for f in "${OLD_FILES[@]}"; do
if $DRY_RUN_DELETE; then
log "INFO" "[DRY-RUN] Будет удалён: $f"
else
if rm -f "$f"; then
log "INFO" "Удалён старый архив: $f"
else
log "WARN" "Не удалось удалить файл: $f"
fi
fi
done
fi
else
log "INFO" "Удаление старых архивов пропущено (флаг --delete-old не передан)"
fi
log "INFO" "=== Скрипт завершён успешно ==="
exit 0
Как использовать
- Сохраните скрипт, например, в
/usr/local/bin/backup_uploads.sh. - Сделайте его исполняемым:
``bash``
sudo chmod +x /usr/local/bin/backup_uploads.sh
- Проверьте вручную в «безопасном» режиме (без удаления):
``bash``
sudo /usr/local/bin/backup_uploads.sh
- Проверьте, что реально будет удалено, не удаляя (dry-run):
``bash``
sudo /usr/local/bin/backup_uploads.sh --dry-run-delete
- Когда убедитесь, что всё работает правильно — запускайте с реальным удалением:
``bash``
sudo /usr/local/bin/backup_uploads.sh --delete-old
- Логи смотрите в
/var/log/backup_uploads.log.
Как поставить в cron (например, каждую ночь в 02:00)
Откройте crontab суперпользователя (так как /var/www обычно требует прав root или www-data):
sudo crontab -e
Добавьте строку:
0 2 * * * /usr/local/bin/backup_uploads.sh --delete-old >> /var/log/backup_uploads_cron.log 2>&1
Пояснения:
0 2 * * *— запуск каждый день в 02:00.--delete-old— явно разрешаем удаление старых архивов (без этого флага скрипт только создаёт бэкап).>> ... 2>&1— дублируем вывод cron в отдельный лог (скрипт и так пишет в свой$LOG_FILE, это дополнительная подстраховка на случай ошибок самого запуска).
Если нужно запускать не от root, а от конкретного пользователя (например, www-data), используйте:
sudo crontab -u www-data -e
и убедитесь, что у этого пользователя есть права на чтение /var/www/site/uploads и запись в /backup.
Конечно, вот скрипт на Bash, который выполняет указанные требования:
#!/bin/bash
# Скрипт для ежедневного архивирования папки и удаления старых архивов.
# --- Конфигурация ---
SOURCE_DIR="/var/www/site/uploads" # Папка, которую нужно архивировать
BACKUP_DIR="/backup" # Папка для хранения архивов
RETENTION_DAYS=14 # Количество дней, в течение которых хранятся архивы
LOG_FILE="/var/log/backup_uploads.log" # Файл для записи логов
# --- Функции ---
# Функция для логирования сообщений
log_message() {
local type="$1" # Тип сообщения (INFO, WARNING, ERROR)
local message="$2" # Само сообщение
echo "$(date '+%Y-%m-%d %H:%M:%S') [$type] $message" | tee -a "$LOG_FILE"
}
# Функция для проверки наличия программы
check_command() {
local cmd="$1"
if ! command -v "$cmd" &> /dev/null; then
log_message "ERROR" "Программа '$cmd' не найдена. Установите ее для работы скрипта."
exit 1
fi
}
# Функция для вывода справки
show_help() {
echo "Использование: $0 [ОПЦИИ]"
echo ""
echo "Этот скрипт архивирует папку '$SOURCE_DIR' в '$BACKUP_DIR'"
echo "и удаляет архивы старше '$RETENTION_DAYS' дней."
echo ""
echo "Опции:"
echo " -d, --delete Удалить старые архивы после создания нового. Без этой опции"
echo " скрипт только создает архив, но не удаляет старые."
echo " -h, --help Показать эту справку и выйти."
echo ""
echo "Пример:"
echo " $0 # Создать архив, но не удалять старые."
echo " $0 --delete # Создать архив и удалить старые."
echo ""
exit 0
}
# --- Проверка входных данных и аргументов ---
DELETE_OLD_ARCHIVES=false
while [[ "$#" -gt 0 ]]; do
case "$1" in
-d|--delete)
DELETE_OLD_ARCHIVES=true
shift
;;
-h|--help)
show_help
;;
*)
log_message "ERROR" "Неизвестная опция: $1"
show_help
;;
esac
done
# --- Основная логика скрипта ---
log_message "INFO" "--- Запуск скрипта архивирования ---"
# 1. Проверка наличия необходимых программ
log_message "INFO" "Проверка наличия необходимых программ (tar, find, mkdir)."
check_command "tar"
check_command "find"
check_command "mkdir"
log_message "INFO" "Все необходимые программы найдены."
# 2. Проверка существования исходной папки
if [[ ! -d "$SOURCE_DIR" ]]; then
log_message "ERROR" "Исходная папка '$SOURCE_DIR' не найдена. Проверьте путь."
exit 1
fi
log_message "INFO" "Исходная папка '$SOURCE_DIR' существует."
# 3. Создание папки для резервных копий, если она не существует
if [[ ! -d "$BACKUP_DIR" ]]; then
log_message "WARNING" "Папка для резервных копий '$BACKUP_DIR' не найдена. Создаю ее."
if ! mkdir -p "$BACKUP_DIR"; then
log_message "ERROR" "Не удалось создать папку для резервных копий '$BACKUP_DIR'. Проверьте права доступа."
exit 1
fi
log_message "INFO" "Папка для резервных копий '$BACKUP_DIR' успешно создана."
fi
# 4. Создание имени файла архива с датой
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
ARCHIVE_NAME="uploads_backup_${TIMESTAMP}.tar.gz"
ARCHIVE_PATH="${BACKUP_DIR}/${ARCHIVE_NAME}"
log_message "INFO" "Начинаю создание архива: '$ARCHIVE_PATH'"
# 5. Создание архива
# -c: создать архив
# -z: сжать gzip
# -f: указать имя файла архива
# -P: не обрезать начальные слэши (сохранять абсолютные пути, если SOURCE_DIR - абсолютный)
# -C: изменить каталог перед добавлением файлов (переходим в родительскую директорию SOURCE_DIR)
# чтобы в архиве не было лишних родительских папок, а сразу содержимое 'uploads'
if ! tar -czPf "$ARCHIVE_PATH" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")"; then
log_message "ERROR" "Ошибка при создании архива '$ARCHIVE_PATH'."
exit 1
fi
log_message "INFO" "Архив '$ARCHIVE_PATH' успешно создан."
log_message "INFO" "Размер архива: $(du -h "$ARCHIVE_PATH" | awk '{print $1}')"
# 6. Удаление старых архивов (только если установлен флаг --delete)
if "$DELETE_OLD_ARCHIVES"; then
log_message "INFO" "Начинаю удаление архивов старше $RETENTION_DAYS дней из '$BACKUP_DIR'."
# -type f: искать только файлы
# -name "*.tar.gz": искать файлы с расширением .tar.gz
# -mtime +N: файлы, измененные более N дней назад
# -delete: удалить найденные файлы
# ВАЖНО: find -delete очень мощная команда, используйте с осторожностью.
# Для отладки можно заменить -delete на -print, чтобы увидеть, что будет удалено.
OLD_ARCHIVES=$(find "$BACKUP_DIR" -type f -name "uploads_backup_*.tar.gz" -mtime +"$RETENTION_DAYS")
if [[ -n "$OLD_ARCHIVES" ]]; then
log_message "INFO" "Будут удалены следующие архивы:"
echo "$OLD_ARCHIVES" | while IFS= read -r file; do
log_message "INFO" " - $file"
done
if ! find "$BACKUP_DIR" -type f -name "uploads_backup_*.tar.gz" -mtime +"$RETENTION_DAYS" -delete; then
log_message "ERROR" "Ошибка при удалении старых архивов."
# Не выходим, так как основной архив уже создан
else
log_message "INFO" "Старые архивы успешно удалены."
fi
else
log_message "INFO" "Старых архивов для удаления не найдено."
fi
else
log_message "INFO" "Флаг --delete не установлен. Старые архивы не будут удалены."
fi
log_message "INFO" "--- Скрипт архивирования завершен ---"
exit 0
Как запустить скрипт:
- Сохраните скрипт:
Сохраните код в файл, например, backup_uploads.sh.
``bash``
nano backup_uploads.sh
- Сделайте скрипт исполняемым:
``bash``
chmod +x backup_uploads.sh
- Запустите скрипт:
- Только создать архив (без удаления старых):
``bash``
./backup_uploads.sh
- Создать архив и удалить старые (старше 14 дней):
``bash``
./backup_uploads.sh --delete
- Проверьте лог:
Логи будут записываться в /var/log/backup_uploads.log. Вы можете просмотреть его:
``bash``
tail -f /var/log/backup_uploads.log
Как поставить в расписание (cron):
Cron — это демон, который запускает команды по расписанию.
- Откройте crontab для редактирования:
``bash`
crontab -e
nano
Если вы запускаете это впервые, вам может быть предложено выбрать текстовый редактор (например, или vim`).
- Добавьте строку в crontab:
Чтобы скрипт запускался каждую ночь, например, в 03:00, добавьте следующую строку в конец файла crontab:
``cron``
0 3 * * * /path/to/backup_uploads.sh --delete
Разберем строку cron:
0: Минута (0-59)3: Час (0-23, где 0 - полночь, 3 - 3 утра)*: День месяца (1-31) - любая*: Месяц (1-12) - любой*: День недели (0-7, где 0 и 7 - воскресенье) - любой/path/to/backup_uploads.sh --delete: Полный путь к вашему скрипту и аргумент--delete. Замените/path/to/на фактический путь, например,/home/user/scripts/backup_uploads.sh.
Пример с полным путем:
Если ваш скрипт находится в /opt/scripts/backup_uploads.sh, строка будет выглядеть так:
``cron``
0 3 * * * /opt/scripts/backup_uploads.sh --delete
- Сохраните и выйдите:
- Если вы используете
nano, нажмитеCtrl+O, затемEnterдля сохранения, иCtrl+Xдля выхода. - Если вы используете
vim, нажмитеEsc, затем:wqиEnter.
Cron автоматически применит изменения. Теперь ваш скрипт будет запускаться каждую ночь в 03:00, создавая новый архив и удаляя старые.
Важные замечания:
- Права доступа: Убедитесь, что пользователь, от имени которого запускается cron (обычно это ваш пользователь или
root), имеет права на чтениеSOURCE_DIR, запись вBACKUP_DIRи запись вLOG_FILE. Для cron-задач, требующих повышенных привилегий (например, доступ к/var/www), часто лучше запускать их от имениroot. Для этого используйтеsudo crontab -e. - Пути: В cron-задачах переменные окружения могут отличаться от вашей интерактивной сессии. Всегда используйте полные пути к исполняемым файлам (например,
/usr/bin/tar,/usr/bin/find) или убедитесь, что ваш скрипт использует полные пути или что PATH правильно установлен в cron-окружении (что менее надежно). В данном скрипте используетсяcommand -v, который найдет команду в PATH, но для cron лучше быть явным. Однако, дляtar,find,mkdirэто обычно не проблема, так как они находятся в стандартных местах. - Тестирование: Всегда сначала тестируйте скрипт вручную, а затем с cron, чтобы убедиться, что он работает как ожидалось.
- Мониторинг: Регулярно проверяйте файл лога
/var/log/backup_uploads.log, чтобы убедиться, что архивирование проходит успешно и нет ошибок. - Безопасность: Скрипт разработан с учетом безопасности: удаление происходит только при явном флаге
--delete. Однако, всегда будьте осторожны с командамиrmиfind -delete. - Имя архива: Имя архива включает дату и время, что позволяет иметь несколько архивов за один день, если скрипт запускается чаще.
Советы
- Проверьте скрипт на тестовой папке, особенно удаление старых файлов.
- Скопируйте промпт кнопкой выше.
- Замените поля в фигурных скобках своими данными.
- Отправьте в нейросеть и сравните ответ с примером на этой странице.
Подробнее о структуре хорошего запроса: гид AI University.
Похожие промпты
Промпты работают лучше, когда понимаешь модель
56 официальных курсов Anthropic, OpenAI, Google и других на русском: первые уроки бесплатно, без VPN. Наборы промптов входят в полный доступ.