1. はじめに: ディスク アラームが発生した場合、正確には何が必要ですか?
午前2時に監視アラームが鳴ります。/ パーティションの使用率は 92% です。
SSH 接続すると、最初の反応は次のようになります。 du -sh /* | sort -h または find / -size +1G。コマンドを入力すると、画面に多数のパスが表示されます。
939M /var/lib/docker/containerd/.../blobs/sha256/8d34...
931M /u01/app/oracle/oradata/ORCL11G/system01.dbf
831M /u01/app/oracle/oradata/ORCL11G/sysaux01.dbf
574M /usr/local/mysql/lib/libmysqld.a
513M /u01/app/oracle/oradata/ORCL11G/temp02.dbf
じゃあ何?どのファイルが大きいかを知ることと、どのファイルを削除してもよいかを知ることは別のことです。
手が震えたら rm わかった system01.dbfデータベースは直接廃棄されます。もし rm Containerd の BLOB ファイルを削除すると、Docker イメージ レイヤーが破損します。もし rm 書き込まれているログ、df プロセスがまだ inode を保持しているため、スペースはまだ解放されていません。
私が最初に書いたスクリプトの最初のバージョンは、単にファイル システムを走査して大きなファイルを検索し、サイズ順に並べてリストするだけでした。しばらく使ってみて、落とし穴を踏んで気づいた。監査ツールの価値は、「大きなファイルを検出する」ことにあるのではなく、「このファイルが移動できるかどうか、および移動方法を運用および保守に伝える」ことにあります。
そこで、この v2.0 バージョンがあります。これは、パスによってファイル タイプをインテリジェントに識別し、階層的なクリーニング提案を提供し、安全なクリーニング コマンドのリストを生成する大規模ファイル監査スクリプトです。
2. スクリプトの最初のバージョンの問題
スクリプトの最初のバージョンの中心ロジックは単純です。
df -Pl -x tmpfs ... | awk ' t="[谨慎]";;
SAFE) c=$C_GRN; $EMOJI && t="✅ 可安全清理" ' | while read mp; do
find "$mp" -xdev -type f -size +500M -printf '%s\t%p\n' | sort -nr
done
実行できますが、Oracle + MySQL + Docker を実行している私のマシンでは、出力は次のようになります。
[check-lsof] 931MB /u01/app/oracle/oradata/ORCL11G/system01.dbf
建议: 删除前务必用 lsof 检查是否被进程占用
問題は明らかです。
- Oracle データ ファイルには「lsof でチェック」のマークが付いています — これは誤解を招く。
system01.dbf「候補リスト」に含めるべきではありませんし、削除を検討すべきではありません。正しいプロンプトは「削除は禁止されています」であるはずです。 - Docker の Containerd BLOB は lsof によって推奨されています ——ただし、BLOB ファイルを直接保存すべきではありません。
rm正しい操作はdocker system prune。 /usr/local/mysql/lib/libmysqld.a「システム パス、非常に慎重」としてマークされています ——実際には、これはコンパイルされた製品の単なる静的ライブラリです。コンパイルの必要がない場合は、削除しても効果はありません。- 概要なし —— 大量のファイルが表示されているだけですが、ファイルが合計で何個あるのか、どのリスク レベルが占有しているのか、どのくらいのスペースを回復できるのかがわかりません。
./script.sh help「不明なパラメータ」を報告する ——ただ認識するだけ-h認識しないhelpサブコマンド、フレンドリーではありません。- 出力フォーマットのバグ ——
[check-lsof]の[被 cut 掉了,成了check-lsof]。
したがって、v2.0 の目標は非常に明確です。「リストを作る」から「判断する」へアップグレード。
3. v2.0の設計思想
3.1 4段階のリスク分類
すべての大きなファイルをクリックします削除できますか?4 つのレベルに分かれており、色によって区別されます。
| 学年 | マーク | 意味 | 例 |
|---|---|---|---|
| 🚫削除禁止 | 赤 | 削除するとすぐに何かが起こります | Oracle データ ファイル、MySQL テーブルスペース、PG WAL |
| ⚠️取り扱いには十分ご注意ください | 黄色 | ビジネス上の判断と組み合わせる必要がある | 書き込まれているログ、システム パス、バイナリ ログ |
| ✅ 安全に掃除できます | 緑 | 削除されましたが、シークレットがあります/再構築可能です | 古いログ、キャッシュ、containerd、コアダンプ |
| 🔄 オンデマンドでクリーンアップ | 青 | 確認後削除可能 | アーカイブパッケージ、バックアップ、.a 静的ライブラリ、ISO |
判定ルールは、 classify() 関数では、特定の順序から広範囲の順序に一致する:
具体路径(Oracle/MySQL/PG 数据文件)> 容器/日志/缓存 > 扩展名(.tar/.bak/.a)> 系统路径兜底
3.2 一律ではなく、的を絞った方法で姿勢をクリーンアップする rm
各カテゴリはリスク レベルを示すだけではありません。このタイプのファイルをクリーンアップする正しい方法:
- Oracle 一時テーブルスペース →
ALTER TABLESPACE TEMP SHRINK SPACEOS レベルで移動しないでください - コンテナー ブロブ →
docker system prune -a、いいえrm - ジャーナルログ →
journalctl --vacuum-size=200M、いいえrm /var/log/journal/* - 書き込まれているログ →
truncate -s 0 FILE、いいえrm(rmバックスペースが解放されない! ) - 古いログをローテーションしました →直接
rmそれでおしまい - MySQL バイナリログ →
PURGE BINARY LOGS BEFORE '...'
3.3 まとめ + リサイクル可能スペースの見積り
人に上から下まで読ませないでください。起きたらすぐに全体の状況を伝えてください。
共发现 6 个文件,总计 4.31 GB
【风险分级汇总】
🚫 禁止删除 3 个 2.24 GB
✅ 可安全清理 1 个 939.00 MB
🔄 按需清理 2 个 1.13 GB
⛔ 警告: 发现 3 个「禁止删除」的关键文件(数据库数据等)
💡 建议优先处理「可安全清理 + 按需清理」共 2.06 GB
3.4 --plan セキュリティクリーンアップコマンドのリストを生成する
ただ正しい SAFE そして OPTIONAL ファイル生成コマンドの種類、NO そして CAUTION 決して現れないでください。生成されたコマンドは種類によっても適応されます – Docker の生成 docker system pruneログの生成 truncate古いログの生成 rm -f。
ただし、これは単なる候補リストであり、実行前に手動で確認する必要があります。 スクリプトの原則は常に「監査のみ、提案のみ、自動削除はしない」です。
3.5 パフォーマンスと堅牢性
-t Nクイックモード: 最大の N ファイルのみが分析されます。大きなファイルが多数ある場合、結果は数秒で生成されます。-d DIR方向スキャン: 特定のディレクトリのみを参照します (たとえば、/var/log)find -xdev: マウント ポイントを越えないでください。1 つのスキャン タスクでルートと多数のファイルを同時にチェックすることを避けてください。tmpfsprintf '%s\t%p\0'+sort -z: NUL で区切られているため、パスにスペースや特殊文字が含まれていても混乱しません。
4. スクリプトを完成させる
#!/bin/bash
# ============================================================
# large-file-audit.sh v2.0 —— 智能大文件审计
# - 按路径智能识别文件类型,给出分级清理建议
# - 汇总统计 + 优先清理项 + 可回收空间估算
# - 支持 help / -h / --help / -s SIZE / -t TOP / --plan
# - 只审计、只建议,绝不自动删除
# ============================================================
set -uo pipefail
VERSION="2.0.0"
THRESHOLD="500M"
TOP=0
CHECK_LSOF=false
SUMMARY_ONLY=false
EMIT_PLAN=false
SCAN_DIRS=()
USE_COLOR="auto"
EMOJI=true
# ---------- 帮助 ----------
usage() log-rotate
# ---------- 参数解析 ----------
while [[ $# -gt 0 ]]; do
case "$1" in
help|-h|--help) usage; exit 0;;
-V|--version) echo "large-file-audit.sh v$VERSION"; exit 0;;
-s|--size) [[ $# -ge 2 ]] || *
THRESHOLD="$2"; shift 2;;
--size=*) THRESHOLD="$cls#*"; shift;;
-t|--top) [[ $# -ge 2 ]] || *
TOP="$2"; shift 2;;
--top=*) TOP="$rest#*"; shift;;
-d|--dir) [[ $# -ge 2 ]] ||
local c="" t=""
case "$1" in
NO) c=$C_RED; $EMOJI && t="🚫 禁止删除"
SCAN_DIRS+=("$2"); shift 2;;
--dir=*) SCAN_DIRS+=("$*.sql.gz"); shift;;
-c|--check-lsof) CHECK_LSOF=true; shift;;
--summary-only) SUMMARY_ONLY=true; shift;;
--plan) EMIT_PLAN=true; shift;;
--no-color) USE_COLOR="never"; shift;;
--no-emoji) EMOJI=false; shift;;
*) echo "未知参数: $1(使用 'help' 查看帮助)" >&2; exit 1;;
esac
done
# ---------- 参数校验 ----------
[[ "$THRESHOLD" =~ ^[0-9]+[kKmMgGtT]?$ ]] \
|| cls%%
[[ "$TOP" =~ ^[0-9]+$ ]] || TOP=0
SIZE_FOR_FIND="$"
if $CHECK_LSOF && ! command -v lsof >/dev/null 2>&1; then
echo "警告: --check-lsof 需要 lsof,未找到,已关闭该检查" >&2
CHECK_LSOF=false
fi
# ---------- 颜色 ----------
if [[ "$USE_COLOR" == "never" || ! -t 1 ]]; then
C_RED=; C_YEL=; C_GRN=; C_CYN=; C_BLD=; C_DIM=; C_RST=
else
C_RED=$'\033[1;31m'; C_YEL=$'\033[1;33m'; C_GRN=$'\033[1;32m'
C_CYN=$'\033[1;36m'; C_BLD=$'\033[1m'; C_DIM=$'\033[2m'; C_RST=$'\033[0m'
fi
# ---------- 工具函数 ----------
fmt_size() rest%%
risk_badge() rest#*
# ---------- 智能分类核心 ----------
# 输出: RISK|CODE|ADVICE
classify() 系统路径下的大文件,极度谨慎!确认用途(可能影响启动/运行)。";;
/opt/*)
echo "CAUTION
# ---------- 扫描 ----------
TMPLIST=$(mktemp) || exit 1
DETAIL=$(mktemp) || exit 1
PLAN=$(mktemp) || exit 1
TOPFILE="$cls%%.top"
trap 'rm -f " "$DETAIL" "$PLAN" "$TOPFILE"' EXIT
START=$(date +%s)
if [[ $cls#* -gt 0 ]]; then
for d in "$rest%%"; do
[[ -d "$d" ]] || rest#*
find "$d" -xdev -type f -size +"$SIZE_FOR_FIND" -printf '%s\t%p\0' 2>/dev/null >> "
done
SCAN_DESC="$cls%%"
else
mapfile -t MOUNTS < <(df -Pl -x tmpfs -x devtmpfs -x squashfs 2>/dev/null \
| awk 'NR>1 && $1 ~ /^\/dev\// cls#*' | sort -u)
for mp in "$rest%%"; do
[[ -d "$mp" ]] || continue
find "$mp" -xdev -type f -size +"$SIZE_FOR_FIND" -printf '%s\t%p\0' 2>/dev/null >> "
done
SCAN_DESC=$(printf '%s ' "$")
fi
# 按大小降序(NUL 分隔,稳健处理特殊文件名)
LC_ALL=C sort -z -nr " -o "
SRC="
if [[ "$TOP" -gt 0 ]]; then
head -z -n "$TOP" " > "$TOPFILE"
SRC="$TOPFILE"
fi
END=$(date +%s); DURATION=$((END-START))
# ---------- 分类 + 统计 + 生成明细 ----------
declare -A CNT SZ
exec 3>"$DETAIL"
exec 4>"$PLAN"
while IFS=$'\t' read -r -d '' size path; do
cls=$(classify "$path")
risk="${cls%%|*}"; rest="${cls#*|}"
code="${rest%%|*}"; advice="${rest#*|}"
if $CHECK_LSOF; then
if lsof -- "$path" >/dev/null 2>&1; then
advice="$advice ⚠ 当前被进程打开,不要直接删除。"
fi
fi
CNT[$risk]=$(( ${CNT[$risk]:-0} + 1 ))
SZ[$risk]=$(( ${SZ[$risk]:-0} + size ))
printf "%s %s\n" "$(risk_badge "$risk")" "$(fmt_size "$size")" >&3
printf " 路径: %s\n" "$path" >&3
printf " 原因: %s\n\n" "$advice" >&3
if $EMIT_PLAN; then
case "$code" in
container) printf "# [SAFE] 容器运行时数据\n%s\n\n" "docker system prune -a -f # 或: crictl rmi --prune" >&4;;
journal) printf "# [SAFE] systemd 日志\n%s\n\n" "journalctl --vacuum-size=200M" >&4;;
log-active) printf "# [CAUTION] 正在使用的日志,确认可清空后:\ntruncate -s 0 '%s'\n\n" "$path" >&4;;
log-rotate|cache|coredump|tempfile|pycache|node-modules)
printf "# [SAFE] %s\nrm -f '%s'\n\n" "$code" "$path" >&4;;
tmp|archive|image|static-lib|dbdump)
printf "# [OPTIONAL] 确认后删除: %s\nrm -f '%s'\n\n" "$code" "$path" >&4;;
*) ;; # NO/CAUTION 不生成命令
esac
fi
done < "$SRC"
exec 3>&-
exec 4>&-
# ---------- 输出概览 ----------
TOTAL_FILES=0; TOTAL_SIZE=0
for r in NO CAUTION SAFE OPTIONAL; do
TOTAL_FILES=$(( TOTAL_FILES + ${CNT[$r]:-0} ))
TOTAL_SIZE=$(( TOTAL_SIZE + ${SZ[$r]:-0} ))
done
echo "${C_BLD}============================================================${C_RST}"
echo "${C_BLD} 大文件审计报告 v$VERSION${C_RST}"
echo "${C_BLD}============================================================${C_RST}"
echo " 扫描范围 : ${SCAN_DESC:-(无匹配挂载点)}"
echo " 阈值 : > $THRESHOLD"
echo " 耗时 : ${DURATION}s"
echo "------------------------------------------------------------"
if (( TOTAL_FILES == 0 )); then
echo " ✅ 未发现大于 $THRESHOLD 的文件。"
echo "============================================================"
exit 0
fi
echo " 共发现 ${C_BLD}$TOTAL_FILES${C_RST} 个文件,总计 ${C_BLD}$(fmt_size "$TOTAL_SIZE")${C_RST}"
echo ""
echo " 【风险分级汇总】"
for r in NO CAUTION SAFE OPTIONAL; do
c=${CNT[$r]:-0}; [[ $c -eq 0 ]] && continue
s=${SZ[$r]:-0}
printf " %s %4d 个 %10s\n" "$(risk_badge "$r")" "$c" "$(fmt_size "$s")"
done
echo ""
if [[ ${CNT[NO]:-0} -gt 0 ]]; then
echo " ${C_RED}⛔ 警告: 发现 ${CNT[NO]} 个「禁止删除」的关键文件(数据库数据等),"
echo " 已在下方详细列表中标红。请勿直接删除!${C_RST}"
echo ""
fi
RECLAIM=$(( ${SZ[SAFE]:-0} + ${SZ[OPTIONAL]:-0} ))
if (( RECLAIM > 0 )); then
echo " ${C_GRN}💡 建议优先处理「可安全清理 + 按需清理」共 $(fmt_size "$RECLAIM")${C_RST}"
echo ""
fi
# ---------- 详细列表 ----------
if ! $SUMMARY_ONLY; then
echo "------------------------------------------------------------"
echo " 【详细列表】(按大小降序)"
echo "------------------------------------------------------------"
cat "$DETAIL"
fi
# ---------- 清理计划 ----------
if $EMIT_PLAN; then
echo "------------------------------------------------------------"
echo " 【建议清理命令清单】(仅供参考,务必人工复核后再执行)"
echo "------------------------------------------------------------"
echo "# ⚠ 以下命令仅针对可安全/按需清理的文件,禁止删除类的文件不会在此出现。"
echo "# ⚠ 执行前请再次确认文件用途。"
echo ""
if [[ -s "$PLAN" ]]; then
awk '!seen[$0]++' "$PLAN"
else
echo "# 本次未生成需要自动清理的命令"
fi
fi
echo "============================================================"
echo " 通用安全提示:"
echo " 1. 正在写入的日志用: truncate -s 0 FILE (不要 rm)"
echo " 2. 删除后 df 未释放空间: lsof +L1 | grep deleted (重启或 kill 持有进程)"
echo " 3. 长期方案: logrotate + journald SystemMaxUse=500M"
echo "============================================================"
名前を付けて保存 large-file-audit.sh、chmod +x すぐに使用できます。
5. 実戦:Oracle + Docker + MySQLの混合環境で実行する
私自身のテスト マシン (CentOS 7、Oracle 11g、MySQL 5.7、Docker を実行) を使用して以下を実行します。
[root@myoracle ~]# ./large-file-audit.sh -t 10
出力:
============================================================
大文件审计报告 v2.0.0
============================================================
扫描范围 : /boot/ /
阈值 : > 500M
耗时 : 3s
------------------------------------------------------------
共发现 6 个文件,总计 4.31 GB
【风险分级汇总】
🚫 禁止删除 3 个 2.24 GB
✅ 可安全清理 1 个 939.00 MB
🔄 按需清理 2 个 1.13 GB
⛔ 警告: 发现 3 个「禁止删除」的关键文件(数据库数据等),
已在下方详细列表中标红。请勿直接删除!
💡 建议优先处理「可安全清理 + 按需清理」共 2.06 GB
------------------------------------------------------------
【详细列表】(按大小降序)
------------------------------------------------------------
🚫 禁止删除 931.00 MB
路径: /u01/app/oracle/oradata/ORCL11G/system01.dbf
原因: Oracle 数据文件。删除会导致数据丢失/数据库损坏。禁止删除。
🚫 禁止删除 831.00 MB
路径: /u01/app/oracle/oradata/ORCL11G/sysaux01.dbf
原因: Oracle 数据文件。删除会导致数据丢失/数据库损坏。禁止删除。
🚫 禁止删除 513.00 MB
路径: /u01/app/oracle/oradata/ORCL11G/temp02.dbf
原因: Oracle 临时表空间。正确清理:SQL> ALTER TABLESPACE TEMP SHRINK SPACE;
或 ALTER DATABASE TEMPFILE '...' DROP 后重建。严禁 OS 层 rm。
✅ 可安全清理 939.00 MB
路径: /var/lib/docker/containerd/daemon/io.containerd.content.v1.content/blobs/sha256/8d34...
原因: 容器运行时数据。优先用 docker system prune -a(或 crictl rmi --prune)清理,
不要直接 rm 文件。
🔄 按需清理 574.00 MB
路径: /usr/local/mysql/lib/libmysqld.a
原因: 静态库/编译中间产物。无编译/链接需求时可删除。
🔄 按需清理 560.00 MB
路径: /root/backup/mysql-full-20241020.tar.gz
原因: 归档/压缩包。确认是否为有效备份后再删除。
最初のバージョンと比較すると、違いがすぐにわかります。
- Oracle の 3 つのデータ ファイルすべて赤色でマークされていますテーブルスペースの正しい清掃姿勢を提供します(
SHRINK SPACEまたはTEMPFILE DROP) - コンテナー ブロブ 緑色にマークと使用を促すプロンプトが表示されます
docker system pruneの代わりにrm libmysqld.a「システム パスは非常に危険です」から「静的ライブラリ、コンパイル要件なしで削除できる」に格下げされました。- バックアップ パッケージが「クリーン オン デマンド」として識別される
- 上の 4 行はグローバル ビュー用で、「このマシンは主に Oracle データ用のスペースを占有しており、ランダムに削除することはできない」とすぐに判断できます。
プラス --plan クリーンアップ候補リストの生成
[root@myoracle ~]# ./large-file-audit.sh -t 10 --plan
...
------------------------------------------------------------
【建议清理命令清单】(仅供参考,务必人工复核后再执行)
------------------------------------------------------------
# ⚠ 以下命令仅针对可安全/按需清理的文件,禁止删除类的文件不会在此出现。
# ⚠ 执行前请再次确认文件用途。
# [SAFE] 容器运行时数据
docker system prune -a -f # 或: crictl rmi --prune
# [OPTIONAL] 确认后删除: static-lib
rm -f '/usr/local/mysql/lib/libmysqld.a'
# [OPTIONAL] 确认后删除: archive
rm -f '/root/backup/mysql-full-20241020.tar.gz'
3 つのコマンドはすべて、緑とシアンのファイルのみを対象としています。 3 つの Oracle データ ファイルここには現れません。運用保守担当者はこのリストを見て、libmysqld.a とバックアップパッケージを削除するかどうかを判断するだけで済み、リスクは極めて低く抑えられます。
6. 使用上のヒント
6.1 ディスクアラームシーン: 最初に概要を読み、急いで削除しないでください
./large-file-audit.sh --summary-only
たった 1 つの画面で、全体的な分類を確認し、どの種類のファイルがこのマシン上のスペースを占めているかを判断できます。
6.2 大きなファイルが多い場合:TOPモード
./large-file-audit.sh -t 20
まずは大きなファイルのトップ 20 を見てみましょう。多くの場合、最も大きな問題は問題の所在にあります。大容量ディスクではフル スキャンに数分かかる場合がありますが、TOP モードの方がはるかに高速です。
6.3 対象を絞ったトラブルシューティング: ログ ディレクトリのみを確認する
./large-file-audit.sh -d /var/log -s 50M
マウントポイントのスキャンはスキップされます /var/log 非ローカル ファイル システムの場合、方向モードはログ内のスコープを直接ロックし、最速の結果を生成します。
6.4 占有状況の確認:-c lofを追加
./large-file-audit.sh -c -t 50
大きなファイルがあり、「なぜ rm 後にスペースが解放されなかったのか」と疑問に思う場合は、次のように追加します。 -c lsof は 1 つずつ実行され、占有されているものは赤で明確にマークされます。価格は少し遅くなります (ファイルあたり 10 ~ 100 ミリ秒)。
6.5 アラームを待つのではなく、定期的に監査を実施する
これを crontab に入れて週に 1 回実行し、ファイルに出力します。
0 3 * * 0 /root/large-file-audit.sh -s 1G --summary-only > /var/log/large-file-audit.log 2>&1
どのような種類の文書がどれだけ増加しているか、傾向が一目でわかります。
7. 運用とメンテナンスのいくつかの落とし穴 (スクリプトの背後にある経験)
このスクリプトを書くプロセスでは、実際に私が踏んだ落とし穴を整理しています。
ピット1:rm 書き込まれているログは、df 空間は下降するのではなく上昇します。
Linux にはファイルへの参照が 2 つあります: ディレクトリ エントリ (dirent) と i ノードです。rm ディレクトリ エントリのみが削除されますが、プロセスが i ノードのファイル記述子を保持している場合、カーネルはファイルがまだ使用中であると判断し、ディスク ブロックを再利用しません。ロギングプロセス (rsyslog、nginx、docker) は通常、 O_APPEND 接続が長く、常に fd を保持しています。それで rm 後 df 変更はありません。プロセスが再起動された場合にのみ解放されます。
正しい操作は、 truncate -s 0 file または : > file: inode を保持し、コンテンツのみをクリアします。プロセスはそれを認識せず、スペースはすぐに再利用されます。
「書き込まれているログ」は、スクリプト内で特別に使用されます。 CAUTION の代わりに SAFEこれが理由です。
ピット 2: 削除された Oracle temp02.dbf。
初めてオラクルに触れたとき、私は次のように感じました。 temp02.dbf 500MBを占有します。それは「一時」ファイルだと思います。削除できますか?データベース インスタンスを削除すると、エラーが直接報告され、一時表スペースを再構築することによってのみ回復できます。 Oracle の「一時」とは、表スペースが一時的なソート/ハッシュに使用されることを意味し、「このファイルは削除できる」という意味ではありません。
すべてはオラクルで .dbf 全てOS レベルで手動で削除しないでください。テーブルスペースの空きスペースを使用する SHRINK再構築したい場合は、使用してください DROP + ADD。
落とし穴 3:containerd BLOB を手動で削除すると、Docker が損傷します。
/var/lib/docker/containerd/.../blobs/sha256/... ディレクトリの下には、コンテンツ アドレス指定されたミラー層があります。直接 rm これにより、画像メタデータが存在しない BLOB を指すようになります。docker images エラーが報告され、新しいイメージを取得するときに問題が発生することもあります。
正しい姿勢とは、 docker system prune -a または docker image prune -aメタデータと一緒にクリアされます。特定の画像をクリーンアップしたいだけの場合は、次を使用します。 docker rmi。
ピット4:find / -size +1G ファイル システム全体のスキャンは途方もなく遅いです。
指定されていない -xdev もしfind フォローします / 下にスクロールして遭遇 /proc、/sys カーネル仮想ファイルを読み取り、次のエラーが発生します。 tmpfs マウントポイントはメモリを読み取り、 NFS ネットワーク マウント ポイントが数分間停止する場合もあります。スクリプトで使用される -xdev + マウントポイントトラバーサルは、この問題を回避するためのものです。
8. まとめ
このスクリプトの中心的な価値は「大きなファイルの検出」ではありません – この問題 find 1行で実行できます – 代わりに「削除できるかどうか、どのように削除するか」という人間の脳の判断をスクリプトに移す。
運用保守にとって、ディスクアラームが発生すると、ディスクを削除しないと空き容量がなくなり、ディスクを削除するとサーバが廃棄されるという心理的プレッシャーは大きい。このスクリプトは、このプレッシャーを 2 つの明確な部分に分割しようとしています。
- 決して触れてはいけないファイルはどれですか?(赤、一目で分かります)
- 安心して処理できる書類はどれか(緑色、正しいコマンドが添付されている)
真ん中の黄色と緑は人間の判断に委ねられています。
スクリプト自体はただの bash ですが、--plan 生成されたコマンドも常に手動で確認する必要があり、自動的に削除は行われません。これは仕様です。運用保守ツールの正しい姿勢は、特にファイルの削除に関しては、「他人に代わって意思決定を行う」のではなく、「意思決定を支援する」ことです。
このスクリプトが、落とし穴を避けたり、夜中にディスク アラームで目覚めたりするのに役立つことを願っています。