Системный Администратор | Sysadmin Windows & Linux Server. Настройка Сети, ПК и Железа. IT Уроки для Сисадмина: Безопасность, Софт и Техподдержка (Helpdesk). Компьютерная помощь.
IT и технологии · 18 июля 2026 г.
📈 Скрипт показывает, какие каталоги выросли с прошлого запуска — 18 июля 2026 г. в 09:14:47.847
📈 Скрипт показывает, какие каталоги выросли с прошлого запуска Скрипт ниже делает снимок размеров каталогов (через du), а при следующем запуске покажет топ приростов - кто вырос и на сколько. #!/usr/bin/env bash # автор: https://t.me/i_odmin set -Eeuo pipefail usage() { cat <<'HELP' Usage: du-delta.sh [-p PATH] [-d DEPTH] [-n TOP] [-t THRESH] [-s STATE_DIR] -p PATH Корень анализа (по умолчанию /) -d DEPTH Глубина du (по умолчанию 2) -n TOP Сколько строк показать (по умолчанию 15) -t THRESH Порог роста (например 100M, 1G; по умолчанию 100M) -s STATE_DIR Директория состояния (по умолчанию /var/lib/du-delta) -h Помощь Прим.: требуются права на чтение анализируемых каталогов. HELP } PATH_TO="/" DEPTH=2 TOP=15 THRESH="100M" STATE_DIR="/var/lib/du-delta" while getopts ":p:d:n:t:s:h" opt; do case "$opt" in p) PATH_TO="$OPTARG" ;; d) DEPTH="$OPTARG" ;; n) TOP="$OPTARG" ;; t) THRESH="$OPTARG" ;; s) STATE_DIR="$OPTARG" ;; h) usage; exit 0 ;; \?) echo "Неизвестный параметр: -$OPTARG" >&2; usage; exit 1 ;; 🙂 echo "Параметру -$OPTARG нужно значение" >&2; exit 1 ;; esac done to_bytes() { local v="$1" if command -v numfmt >/dev/null 2>&1; then numfmt --from=iec "$v" else awk -v s="$v" 'BEGIN{ n=s; sub(/[KkMmGgTtPp][Bb]?$/,"",n); u=""; if (match(s,/[KkMmGgTtPp]/)) u=substr(s,RSTART,1); m=1; if(u=="K"||u=="k") m=1024; else if(u=="M"||u=="m") m=1024^2; else if(u=="G"||u=="g") m=1024^3; else if(u=="T"||u=="t") m=1024^4; else if(u=="P"||u=="p") m=1024^5; printf "%d", n*m }' fi } human() { local b="$1" if command -v numfmt >/dev/null 2>&1; then numfmt --to=iec --suffix=B "$b" else awk -v b="$b" 'function h(x, a,i){ split("B KiB MiB GiB TiB PiB",a," "); for(i=1; x>=1024 && i<6; i++) x/=1024; return sprintf("%.1f %s", x, a[i]) } BEGIN{print h(b)}' fi } # Определяем совместимый ключ глубины для du if du -d 0 / >/dev/null 2>&1; then DU_DEPTH=(-d "$DEPTH") else DU_DEPTH=(--max-depth="$DEPTH") fi mkdir -p "$STATE_DIR" chmod 700 "$STATE_DIR" # Имя снапшота зависит от пути и глубины safe_name="$(echo "$PATH_TO" | sed 's|/|_|g; s|^_$|root|')_d${DEPTH}.tsv" SNAP_FILE="$STATE_DIR/$safe_name" tmp_cur="$(mktemp)" trap 'rm -f "$tmp_cur"' EXIT # Снимок текущих размеров: "path \t bytes" # -B1: байты, -x: не вылезать на другие ФС, --apparent-size: по желанию (коммент ниже) # Уберите --apparent-size, если хотите считать выделенные блоки, а не логический размер. du -B1 "${DU_DEPTH[@]}" -x --apparent-size "$PATH_TO" 2>/dev/null \ | awk 'BEGIN{OFS="\t"} {sz=$1; $1=""; sub(/^[ \t]+/,""); print $0, sz}' \ | sort -k1,1 > "$tmp_cur" # Если есть предыдущий снимок — считаем дельты THRESH_BYTES="$(to_bytes "$THRESH")" printf "📈 Топ %d приростов в %s (глубина %d, порог %s):\n" \ "$TOP" "$PATH_TO" "$DEPTH" "$THRESH" if [[ -s "$SNAP_FILE" ]]; then awk -F'\t' -v th="$THRESH_BYTES" ' NR==FNR { prev[$1]=$2; next } { cur=$2+0; p=(($1 in prev)?prev[$1]+0:0); d=cur-p; if (d>=th) { print $1 "\t" d } } ' "$SNAP_FILE" "$tmp_cur" \ | sort -k2,2nr \ | head -n "$TOP" \ | awk -F'\t' '{printf " + %-8s %s\n", "'"$(human "$2")"'", $1}' \ || true else echo " (первый запуск — снимаю базовую метрику, сравнивать не с чем)" fi # Обновляем снимок mv -f "$tmp_cur" "$SNAP_FILE" - Быстрый запуск вручную: sudo bash du-delta.sh -p /var -d 3 -t 200M -n 20 - Повесить на cron (каждые 6 часов) и писать в syslog: */6 * * * * root /usr/local/sbin/du-delta.sh -p / -d 3 -t 200M -n 20 | logger -t du-delta Хочешь логический размер файлов (как видит ls -l) - оставляй --apparent-size. Нужен именно занятый на диске объём - убери этот флаг. 💡 Начни с -d 2 для обзора верхних уровней, потом точечно спускайся глубже по «подозрительным» каталогам. 👉 @i_odmin

