Универсальный bash‑скрипт для безопасного уменьшения изображений (с бэкапом и сохранением имён)
готовый скрипт, который рекурсивно проходит по каталогу, уменьшает большие изображения до заданного порога, делает бэкап только изменённых файлов, сохраняет исходные имена, поддерживает dry‑run и выбор форматов. Идеален для рабочих директорий upload/ в Bitrix/WordPress и массивов контент‑фото.
это готовый скрипт, который рекурсивно проходит по каталогу, уменьшает большие изображения до заданного порога, делает бэкап только изменённых файлов, сохраняет исходные имена, поддерживает dry‑run и выбор форматов. Идеален для рабочих директорий upload/ в Bitrix/WordPress и массивов контент‑фото.
Зачем это нужно
- Нет падений PHP из‑за «переростков»: уменьшенные фото меньше нагружают
GD/Imagickи не выбиваютmemory_limit. - Экономия диска и трафика: меньше мегабайт → быстрее страницы, ниже нагрузка на CDN/сервер.
- Безопасно: перед изменением скрипт положит оригинал в каталог бэкапа с сохранением структуры → всегда можно откатиться.
- Просто: один файл, без зависимостей кроме
ImageMagick.
Что требуется
- Linux/macOS (bash).
- Пакет
ImageMagick:- Ubuntu/Debian:
sudo apt install imagemagick - CentOS/RHEL/Rocky/Alma:
sudo yum install ImageMagick - Проверка:
identify -versionилиmagick -version.
- Ubuntu/Debian:
Что умеет скрипт
- Рекурсивно обходит указанный каталог, игнорируя папку бэкапа.
- Уменьшает пропорционально, чтобы длинная сторона ≤ MAX (по умолчанию 2000 px). Маленькие файлы не трогает.
- Перед изменением копирует оригинал в
backup_YYYYmmdd_HHMMSS/…с сохранением дерева подпапок. - Сохраняет имена файлов (перезаписывает уменьшенной версией).
- Поддерживает dry‑run (прогон без изменений) и выбор расширений.
По умолчанию обрабатываются: jpg,jpeg,png. Можно добавить gif (не рек. для анимированных) или другие.
Код скрипта img-shrink-backup.sh
#!/usr/bin/env bash
# ---------- проверка ImageMagick ----------
# Поддерживаем два интерфейса: identify/mogrify или magick identify|mogrify
ID_CMD=(identify)
MG_CMD=(mogrify)
if ! command -v "${ID_CMD[0]}" >/dev/null || ! command -v "${MG_CMD[0]}" >/dev/null; then
if command -v magick >/dev/null; then
ID_CMD=(magick identify)
MG_CMD=(magick mogrify)
else
echo "Ошибка: ImageMagick не найден. Установите пакет (identify/mogrify или 'magick')." >&2
exit 1
fi
}
# ---------- подготовка ----------
DIR="${DIR%/}"
if [[ -z "$BACKUP_DIR" ]]; then
TS="$(date +%Y%m%d_%H%M%S)"
BACKUP_DIR="$DIR/backup_${TS}"
fi
mkdir -p "$BACKUP_DIR"
IFS=',' read -r -a EXTS <<< "$EXT_LIST"
FIND_EXPR=()
for ext in "${EXTS[@]}"; do
FIND_EXPR+=( -iname "*.${ext}" -o )
done
unset 'FIND_EXPR[${#FIND_EXPR[@]}-1]' 2>/dev/null || true
echo "Каталог: $DIR"
echo "Порог: ${MAX}px по длинной стороне"
echo "Расширения: ${EXT_LIST}"
echo "Бэкап в: $BACKUP_DIR"
[[ "$DRYRUN" -eq 1 ]] && echo "Режим: DRY-RUN (без изменений)"
COUNT_TOTAL=0
COUNT_RESIZED=0
while IFS= read -r -d '' FILE; do
(( COUNT_TOTAL++ )) || true
if ! DIM="$(${ID_CMD[@]} -format '%w %h' -- "$FILE" 2>/dev/null)"; then
echo "Пропуск (не удалось определить размер): ${FILE#$DIR/}" >&2
continue
fi
WIDTH=${DIM%% *}
HEIGHT=${DIM##* }
if (( WIDTH > MAX || HEIGHT > MAX )); then
REL="${FILE#$DIR/}"
BFILE="$BACKUP_DIR/$REL"
if [[ "$DRYRUN" -eq 1 ]]; then
echo "[DRY] ${REL} (${WIDTH}x${HEIGHT} -> <= ${MAX})"
continue
fi
mkdir -p -- "$(dirname -- "$BFILE")"
cp -p -- "$FILE" "$BFILE"
${MG_CMD[@]} -resize "${MAX}x${MAX}>" -- "$FILE"
NEW_DIM="$(${ID_CMD[@]} -format '%w %h' -- "$FILE" 2>/dev/null || echo "")"
echo "[OK ] ${REL} (${WIDTH}x${HEIGHT} -> ${NEW_DIM})"
(( COUNT_RESIZED++ )) || true
else
echo "[=] ${FILE#$DIR/} (${WIDTH}x${HEIGHT}, <= ${MAX})"
fi
done < <( find "$DIR" -type d -path "$BACKUP_DIR" -prune -o -type f \( "${FIND_EXPR[@]}" \) -print0 )
echo "Готово. Обработано файлов: $COUNT_TOTAL; уменьшено: $COUNT_RESIZED"
⚠️ По умолчанию скрипт не трогает EXIF/метаданные и не меняет качество JPEG. Это безопасно. В конце статьи есть раздел «Доп. опции», где показано, как добавить -strip и -quality при необходимости.
Установка и запуск
- Сохраните файл:
nano img-shrink-backup.sh # вставьте код выше chmod +x img-shrink-backup.sh - Пробный запуск (ничего не меняет):
./img-shrink-backup.sh -n /var/www/your-site/upload - Реальная обработка с настройками по умолчанию (2000 px):
./img-shrink-backup.sh /var/www/your-site/upload
Примеры использования
- Изменить порог до 2400 px:
./img-shrink-backup.sh -m 2400 /data/images - Добавить форматы (например, ещё и GIF):
./img-shrink-backup.sh -e jpg,jpeg,png,gif /data/pics - Сохранить бэкап в конкретное место:
./img-shrink-backup.sh -b /var/backups/images_$(date +%F) /var/www/site/upload - Получить абсолютный путь к текущей папке и запустить:
./img-shrink-backup.sh "$(pwd)"
Как восстановить файлы из бэкапа
Все оригиналы лежат в каталоге backup_YYYYmmdd_HHMMSS (или вашем -b).
- Восстановить один файл:
cp -p backup_20250101_120000/path/to/image.jpg path/to/image.jpg - Восстановить всё дерево:
rsync -a backup_20250101_120000/ ./
Советы и частые вопросы
- Сохраняются ли имена файлов? Да, меняется только содержимое — имя остаётся.
- Что с качеством и EXIF? По умолчанию не трогаем. Если нужно сильнее ужать JPEG, добавьте к строке с
mogrifyопции-strip -quality 82:${MG_CMD[@]} -strip -quality 82 -resize "${MAX}x${MAX}>" -- "$FILE" - Анимированные GIF? Скрипт уменьшит первый кадр у некоторых сборок ImageMagick или попытается перерасчитать все кадры — это дорого. Лучше исключить большие GIF или обрабатывать их отдельно.
- HEIC/WEBP? Если в вашей сборке ImageMagick включена поддержка — можно добавить расширения в
-e. Для HEIC иногда требуется пакетlibheif. - CMYK‑JPEG из типографий? Могут выглядеть «тускло» в вебе. Скрипт их не переколорит. При необходимости добавляйте профили вручную (
-colorspace sRGB). - Можно быстрее? Для больших массивов файлов используйте GNU parallel или запускайте скрипт по расписанию через cron. Также помогает выполнение на SSD и локальном диске.
Интеграция в рабочий процесс
- Перед импортами (1С, парсеры, контент‑миграции) прогоняйте папку входящих изображений.
- После загрузки контент‑менеджерами — крон‑задача раз в час/ночь.
- Перед сборкой статики/CDN‑инвалидацией — как часть CI/CD шага.
Пример cron (ежедневно в 02:30):
30 2 * * * /opt/tools/img-shrink-backup.sh -m 2000 -e jpg,jpeg,png /var/www/site/upload >> /var/log/img-shrink.log 2>&1
Чем это полезно бизнесу и разработчикам
- Стабильность: меньше рисков упасть из‑за памяти при генерации ресайзов/WEBP.
- Производительность: ускорение LCP/CLS, рост Core Web Vitals.
- Экономия: меньше места и трафика → ниже счета за хостинг/CDN.
- Контроль: бэкап на каждый изменённый файл, прозрачные логи и лёгкий откат.
Доп. опции (по желанию)
- Жёстче сжимать JPEG:
-quality 80..85. - Убирать метаданные:
-strip. - Принудительно переводить в sRGB:
-colorspace sRGB. - Исключить отдельные подпапки: добавьте условия к
find.