ΠŸΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ содСрТимому
ΠœΠ°ΠΊΡΠΈΠΌΠ΅Ρ‚Π΅Ρ€

πŸ“ˆ Π‘ΠΊΡ€ΠΈΠΏΡ‚ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊΠΈΠ΅ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ выросли с ΠΏΡ€ΠΎΡˆΠ»ΠΎΠ³ΠΎ запуска

πŸ“ˆ Π‘ΠΊΡ€ΠΈΠΏΡ‚ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊΠΈΠ΅ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ выросли с ΠΏΡ€ΠΎΡˆΠ»ΠΎΠ³ΠΎ запуска Π‘ΠΊΡ€ΠΈΠΏΡ‚ Π½ΠΈΠΆΠ΅ Π΄Π΅Π»Π°Π΅Ρ‚ снимок Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ² (Ρ‡Π΅Ρ€Π΅Π· 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

1Β 590 просмотров

Канал Π² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ ΠœΠ°ΠΊΡΠΈΠΌΠ΅Ρ‚Π΅Ρ€Π°

6Β 171 подписчиков Β· IT ΠΈ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ

Π”Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΊΠ°Π½Π°Π»Π°

ΠŸΠΎΠΏΡƒΠ»ΡΡ€Π½Ρ‹Π΅ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΊΠ°Π½Π°Π»Π°

Π•Ρ‰Ρ‘ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅ Β«IT ΠΈ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈΒ»

Π§ΠΈΡ‚Π°Ρ‚ΡŒ дальшС

Π”Π²Π° Ρ€Π°Π·Π° Π² нСдСлю свСТиС посты этого ΠΊΠ°Π½Π°Π»Π° β€” Π½Π° ΠΏΠΎΡ‡Ρ‚Ρƒ ΠΈ Π² Π»ΠΈΡ‡Π½ΡƒΡŽ Π»Π΅Π½Ρ‚Ρƒ. Π‘Π΅Π· ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ поиска ΠΊΠ°Π½Π°Π»Π° Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.