#!/usr/bin/env bash
# ==============================================================================
# 脚本名称: check_deleted_files.sh
# 功能描述: 自动扫描内存中尚未释放的已删除文件句柄,并检查防误删机制 (纯只读)
# 使用方式: 在 Linux 宿主机以 root 权限执行
# ==============================================================================
set -o pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
PLAIN='\033[0m'
echo -e "${BLUE}================================================================${PLAIN}"
echo -e "${BLUE} Linux 误删文件句柄扫描与防御基线巡检脚本 ${PLAIN}"
echo -e "${BLUE}================================================================${PLAIN}"
# 1. 扫描当前可通过内存句柄 100% 恢复的已删除文件
echo -e "\n${YELLOW}[1/2] 扫描当前系统中已删除但仍被进程占用的文件 (可无损提取)...${PLAIN}"
if ! command -v lsof &>/dev/null; then
echo -e " -> ${RED}[ERROR] 当前系统未安装 lsof 工具,无法扫描进程句柄。${PLAIN}"
else
DELETED_FILES=$(lsof +L1 2>/dev/null | awk '$NF == "(deleted)" && $5 == "REG" {print $0}' | head -n 15)
if [ -n "$DELETED_FILES" ]; then
echo -e " -> ${RED}[发现目标] 以下文件已被删除,但文件描述符仍在内存中存活:${PLAIN}"
echo -e " ${BLUE}进程名 PID 用户 FD 大小(Bytes) 原文件路径${PLAIN}"
echo "$DELETED_FILES" | awk '{printf " %-12s %-8s %-8s %-6s %-12s %s\n", $1, $2, $3, $4, $7, $9}'
echo -e "\n -> ${GREEN}[恢复指南] 若需恢复上述文件,请提取对应的 PID 与 FD (仅保留数字部分),执行:${PLAIN}"
echo -e " ${YELLOW}cp /proc/<PID>/fd/<FD数字> /tmp/recovered_file${PLAIN}"
echo -e " -> ${YELLOW}[空间释放] 若上述文件为预期清理的巨大日志且占满磁盘,可执行以下命令在线清空释放空间:${PLAIN}"
echo -e " ${YELLOW}: > /proc/<PID>/fd/<FD数字>${PLAIN}"
else
echo -e " -> ${GREEN}[OK] 当前未检测到处于 deleted 状态且被进程占用的常规文件。${PLAIN}"
fi
fi
# 2. 检查本地防误删保护机制
echo -e "\n${YELLOW}[2/2] 检查系统防误删保护配置...${PLAIN}"
if command -v trash-put &>/dev/null; then
echo -e " -> ${GREEN}[OK] 系统已安装 trash-cli 回收站组件,具备文件误删缓冲防线。${PLAIN}"
else
echo -e " -> ${YELLOW}[INFO] 系统未安装 trash-cli 回收站工具。${PLAIN}"
fi
if grep -q "alias rm=" /etc/bashrc /etc/profile ~/.bashrc 2>/dev/null; then
echo -e " -> ${GREEN}[OK] 环境变量中已配置 rm 别名保护。${PLAIN}"
else
echo -e " -> ${RED}[WARN] 未检测到全局 rm 保护别名,执行 rm -rf 存在直接抹除数据的风险。${PLAIN}"
echo -e " -> ${GREEN}[加固建议] 建议引入 trash-cli 接管删除操作,或在 /etc/profile.d/ 下配置安全拦截函数。${PLAIN}"
fi
echo -e "\n${BLUE}================================================================${PLAIN}"