
我们使用宝塔邮局,有时候磁盘满了,无法使用,特别是smtp无法发送邮件

这时候需要清理服务器的磁盘才能正常使用那么怎么清理服务器磁盘呢?本教程来介绍这个清理问题。
1、连上服务器的ssh
2、清理日志文件
a 清理正在使用日志(此命令不是删除,是清理,删除会导致服务器崩溃,可以直接执行本命令)
bash
sudo truncate -s 0 /var/log/syslog
b 删除以前自动日志的自动备份文件
bash
sudo find /var/log -name "*.gz" -o -name "*.bz2" -o -name "*.[0-9]" -exec rm -f {} \;
3、宝塔邮局邮件清理
本脚本只清理邮件,不删除账户
bash
# 创建脚本文件
cat > /root/mail_cleaner.sh << 'EOF'
#!/bin/bash
echo "=== 邮件文件夹清理工具(交互版)==="
# 记录开始时间
START_TIME=$(date +%s)
# 查找所有域名
MAIL_BASE="/www/vmail"
DOMAINS=($(find "$MAIL_BASE" -maxdepth 1 -type d -exec basename {} \; | grep -v "^vmail$" | sort))
# 检查是否有域名
if [ ${#DOMAINS[@]} -eq 0 ]; then
echo "错误:在 $MAIL_BASE 下未找到任何域名!"
exit 1
fi
# 显示域名列表
echo "可用的域名列表:"
echo "0. 全部清理 (all)"
for i in "${!DOMAINS[@]}"; do
echo "$((i+1)). ${DOMAINS[$i]}"
done
# 用户选择域名(直接回车默认全部清理)
echo ""
echo -n "请选择要清理的域名 (输入数字 0-${#DOMAINS[@]} 或 all,直接回车默认全部清理): "
read choice
# 处理域名选择(直接回车默认为全部清理)
if [[ "$choice" == "0" || "$choice" == "all" || "$choice" == "全部" || -z "$choice" ]]; then
SELECTED_DOMAINS=("${DOMAINS[@]}")
if [[ -z "$choice" ]]; then
echo "您选择了:全部清理(默认)"
else
echo "您选择了:全部清理"
fi
else
# 检查输入是否有效
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#DOMAINS[@]} ]; then
index=$((choice-1))
SELECTED_DOMAINS=("${DOMAINS[$index]}")
echo "您选择了:${DOMAINS[$index]}"
else
echo "错误:无效的选择!"
exit 1
fi
fi
# 清理范围选择
echo ""
echo "请选择清理范围:"
echo "1. 清理发件箱 (cur、tmp 目录)"
echo "2. 清理收件箱 (new、tmp 目录)"
echo "3. 全部清理 (cur、new、tmp 目录)"
echo -n "请输入选择 (直接回车默认3-全部清理): "
read cleanup_scope
# 处理清理范围选择
case "$cleanup_scope" in
"1")
FOLDERS=("cur" "tmp")
SCOPE_NAME="发件箱 (cur、tmp)"
;;
"2")
FOLDERS=("new" "tmp")
SCOPE_NAME="收件箱 (new、tmp)"
;;
"3"|"")
FOLDERS=("cur" "new" "tmp")
SCOPE_NAME="全部邮箱 (cur、new、tmp)"
;;
*)
echo "错误:无效的清理范围选择!"
exit 1
;;
esac
if [[ -z "$cleanup_scope" ]]; then
echo "您选择了:$SCOPE_NAME(默认)"
else
echo "您选择了:$SCOPE_NAME"
fi
# 确认操作(直接回车默认为y)
echo ""
echo "========================================"
echo "即将执行以下操作:"
echo "- 清理域名: ${SELECTED_DOMAINS[*]}"
echo "- 清理范围: $SCOPE_NAME"
echo "========================================"
echo -n "确认开始清理吗?(Y/n,直接回车默认确认): "
read confirm
# 处理确认选择(直接回车、y、Y 都确认为继续)
if [[ "$confirm" =~ ^[Nn]$ ]]; then
echo "操作已取消"
exit 0
else
echo "确认执行清理操作..."
fi
# 清理函数(带进度显示)
clean_domain() {
local domain="$1"
echo ""
echo "====== 开始清理域名: $domain ======"
local mail_base="/www/vmail/$domain"
local mail_users=($(find "$mail_base" -maxdepth 1 -type d -exec basename {} \; | grep -v "^$domain$" | sort))
if [ ${#mail_users[@]} -eq 0 ]; then
echo "在 $domain 下未找到任何邮箱账号"
return
fi
local total_cleaned=0
local total_accounts=0
local total_users=${#mail_users[@]}
local current_user=0
echo "该域名下共有 $total_users 个邮箱账号需要处理"
echo "----------------------------------------"
for user in "${mail_users[@]}"; do
if [ -n "$user" ]; then
current_user=$((current_user + 1))
user_dir="$mail_base/$user"
# 显示进度
echo "[$current_user/$total_users] 处理账号: $user"
local user_cleaned=0
for folder in "${FOLDERS[@]}"; do
target_dir="$user_dir/$folder"
if [ -d "$target_dir" ] && [ "$(ls -A "$target_dir")" ]; then
file_count=$(ls -1 "$target_dir" | wc -l)
echo " 清理: $folder/ ($file_count 个文件)"
rm -rf "$target_dir"/*
user_cleaned=$((user_cleaned + file_count))
fi
done
total_cleaned=$((total_cleaned + user_cleaned))
total_accounts=$((total_accounts + 1))
if [ $user_cleaned -gt 0 ]; then
echo " ✓ 此账号清理了 $user_cleaned 个文件"
else
echo " ○ 此账号无需清理"
fi
# 显示剩余账号和进度百分比
remaining=$((total_users - current_user))
progress=$((current_user * 100 / total_users))
echo " 进度: $progress% | 剩余: $remaining 个账号"
echo " ------------------------------------"
fi
done
echo "✓ 域名 $domain 清理完成: $total_accounts 个账号, 共 $total_cleaned 个文件"
}
# 格式化时间函数
format_duration() {
local total_seconds=$1
if [ $total_seconds -lt 60 ]; then
echo "${total_seconds}秒"
elif [ $total_seconds -lt 3600 ]; then
minutes=$((total_seconds / 60))
seconds=$((total_seconds % 60))
echo "${minutes}分钟${seconds}秒"
else
hours=$((total_seconds / 3600))
minutes=$(( (total_seconds % 3600) / 60 ))
seconds=$((total_seconds % 60))
echo "${hours}小时${minutes}分钟${seconds}秒"
fi
}
# 主清理流程
echo ""
echo "开始清理操作..."
echo "========================================"
# 停止邮件服务
echo "停止邮件服务..."
MAIL_START_TIME=$(date +%s)
sudo bt stop mail
# 执行清理
TOTAL_DOMAINS=${#SELECTED_DOMAINS[@]}
CURRENT_DOMAIN=0
for domain in "${SELECTED_DOMAINS[@]}"; do
CURRENT_DOMAIN=$((CURRENT_DOMAIN + 1))
echo ""
echo ">>> 正在处理域名 [$CURRENT_DOMAIN/$TOTAL_DOMAINS]: $domain"
DOMAIN_START_TIME=$(date +%s)
clean_domain "$domain"
DOMAIN_END_TIME=$(date +%s)
DOMAIN_DURATION=$((DOMAIN_END_TIME - DOMAIN_START_TIME))
echo ">>> 域名 $domain 处理耗时: $(format_duration $DOMAIN_DURATION)"
echo "========================================"
done
# 重启邮件服务
echo ""
echo "重启邮件服务..."
sudo bt start mail
MAIL_END_TIME=$(date +%s)
MAIL_DURATION=$((MAIL_END_TIME - MAIL_START_TIME))
# 计算邮件清理阶段耗时
CLEAN_END_TIME=$(date +%s)
CLEAN_DURATION=$((CLEAN_END_TIME - START_TIME))
echo ""
echo "=== 邮件清理操作完成 ==="
echo "清理范围: $SCOPE_NAME"
echo "处理域名: ${SELECTED_DOMAINS[*]}"
echo "邮件清理耗时: $(format_duration $MAIL_DURATION)"
echo "总运行时间: $(format_duration $CLEAN_DURATION)"
echo ""
# 询问是否清理系统日志
echo "========================================"
echo -n "是否安全清理系统日志?可能占用很大 (y/N,直接回车默认不清理): "
read clean_logs
if [[ "$clean_logs" =~ ^[Yy]$ ]]; then
echo ""
echo "开始清理系统日志..."
LOG_START_TIME=$(date +%s)
# 清理当前系统日志
echo "正在清理使用中的系统日志..."
sudo truncate -s 0 /var/log/syslog 2>/dev/null || true
sudo truncate -s 0 /var/log/messages 2>/dev/null || true
sudo truncate -s 0 /var/log/maillog 2>/dev/null || true
echo "✓ 安全清理使用中的日志完成"
# 清理压缩的旧日志文件
echo "正在清理备份的早期日志..."
sudo find /var/log -name "*.gz" -o -name "*.bz2" -o -name "*.[0-9]" -exec rm -f {} \; 2>/dev/null || true
echo "✓ 清理备份的早期日志完成"
# 清理宝塔日志
echo "正在清理宝塔面板日志..."
sudo find /www/server/panel/logs -name "*.log" -exec truncate -s 0 {} \; 2>/dev/null || true
echo "✓ 清理宝塔面板日志完成"
LOG_END_TIME=$(date +%s)
LOG_DURATION=$((LOG_END_TIME - LOG_START_TIME))
echo "系统日志清理完成!耗时: $(format_duration $LOG_DURATION)"
else
echo "跳过系统日志清理"
fi
# 显示磁盘使用情况
echo ""
echo "========================================"
echo "当前磁盘使用情况:"
echo "========================================"
df -h | awk '
NR==1 {
print "文件系统 容量 已用 可用 已用% 挂载点"
print "--------------------------------------------"
}
NR>1 {
printf "%-12s %5s %5s %5s %5s %s\n", $1, $2, $3, $4, $5, $6
}'
# 计算总耗时
END_TIME=$(date +%s)
TOTAL_DURATION=$((END_TIME - START_TIME))
echo ""
echo "========================================"
echo "=== 所有操作完成 ==="
echo "总耗时: $(format_duration $TOTAL_DURATION)"
echo "完成时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "========================================"
EOF
# 赋予执行权限
chmod +x /root/mail_cleaner.sh
# 执行脚本
/root/mail_cleaner.sh
邮局清理高级版
大部分情况,账号的文件夹下,还有大量的索引文件,邮件都删了,这些索引文件也没啥用了,这个命令可以连着索引一起清理了
bash
if [ -f /usr/bin/curl ];then curl -sSO https://www.ouyun.cc/dz/jb/btmailclearpro.sh;else wget -O btmailclearpro.sh https://www.ouyun.cc/dz/jb/btmailclearpro.sh;fi;bash btmailclearpro.sh
下面是原始代码供参考
bash
#!/bin/bash
# =====================================================
# 邮件文件夹清理工具(增强版)- 远程执行适配版
# 放在: www.ouyun.cc/dz/jb/btmailclearpro.sh
# 执行: curl -sSO https://www.ouyun.cc/dz/jb/btmailclearpro.sh && bash btmailclearpro.sh
# =====================================================
# 设置脚本所在目录为工作目录(防止相对路径问题)
cd "$(dirname "$0")" || exit 1
# 颜色输出函数(可选,让输出更美观)
red() { echo -e "\033[31m$1\033[0m"; }
green() { echo -e "\033[32m$1\033[0m"; }
yellow() { echo -e "\033[33m$1\033[0m"; }
blue() { echo -e "\033[34m$1\033[0m"; }
# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
red "错误:请使用 root 权限执行此脚本"
red "请运行: sudo bash btmailclearpro.sh"
exit 1
fi
# 检查必要的命令是否存在
check_command() {
if ! command -v "$1" &> /dev/null; then
yellow "警告: 未找到命令 '$1'"
return 1
fi
return 0
}
# 检查必要命令
check_command "find" || exit 1
check_command "du" || exit 1
check_command "truncate" || {
yellow "安装 truncate 工具..."
if command -v apt-get &> /dev/null; then
apt-get update && apt-get install -y coreutils
elif command -v yum &> /dev/null; then
yum install -y coreutils
fi
}
# 检查邮件目录是否存在
MAIL_BASE="/www/vmail"
if [ ! -d "$MAIL_BASE" ]; then
red "错误:邮件目录 $MAIL_BASE 不存在!"
red "请确认是否安装了宝塔面板邮件服务"
exit 1
fi
# 检查根目录下的数据库文件(作为提示)
echo "====================================================="
green " 邮件文件夹清理工具 v2.3(简化版)"
echo "====================================================="
echo "脚本运行目录: $(pwd)"
echo "系统信息: $(uname -s) $(uname -m)"
echo "执行时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "====================================================="
# 显示根目录的数据库文件(提示用户这些文件会被保护)
ROOT_DB_FILES=$(find "$MAIL_BASE" -maxdepth 1 -name "*.db" -o -name "*.sqlite" -o -name "*.sqlite3" 2>/dev/null)
if [ -n "$ROOT_DB_FILES" ]; then
yellow "检测到根目录数据库文件(将会被保护,不会被清理):"
echo "$ROOT_DB_FILES" | while read -r db_file; do
echo " 📁 保护: $db_file"
done
echo "====================================================="
fi
# 记录开始时间
START_TIME=$(date +%s)
# 查找所有域名
echo "正在扫描邮件域名..."
DOMAINS=($(find "$MAIL_BASE" -maxdepth 1 -type d ! -name "vmail" ! -name "lost+found" -exec basename {} \; 2>/dev/null | sort))
# 检查是否有域名
if [ ${#DOMAINS[@]} -eq 0 ]; then
red "错误:在 $MAIL_BASE 下未找到任何域名!"
exit 1
fi
# 显示域名列表
echo ""
blue "可用的域名列表:"
echo "0. 全部清理 (all)"
for i in "${!DOMAINS[@]}"; do
echo " $((i+1)). ${DOMAINS[$i]}"
done
# 用户选择域名
echo ""
echo -n "请选择要清理的域名 (输入数字 0-${#DOMAINS[@]},直接回车默认全部清理): "
read choice
# 处理域名选择
if [[ "$choice" == "0" || "$choice" == "all" || "$choice" == "全部" || -z "$choice" ]]; then
SELECTED_DOMAINS=("${DOMAINS[@]}")
if [[ -z "$choice" ]]; then
green "您选择了:全部清理(默认)"
else
green "您选择了:全部清理"
fi
else
# 检查输入是否有效
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le ${#DOMAINS[@]} ]; then
index=$((choice-1))
SELECTED_DOMAINS=("${DOMAINS[$index]}")
green "您选择了:${DOMAINS[$index]}"
else
red "错误:无效的选择!"
exit 1
fi
fi
# 清理范围选择
echo ""
blue "请选择清理范围:"
echo "1. 清理发件箱 (cur、tmp 目录)"
echo "2. 清理收件箱 (new、tmp 目录)"
echo "3. 全部清理 (cur、new、tmp 目录)"
echo -n "请输入选择 (直接回车默认3-全部清理): "
read cleanup_scope
# 处理清理范围选择
case "$cleanup_scope" in
"1")
FOLDERS=("cur" "tmp")
SCOPE_NAME="发件箱 (cur、tmp)"
;;
"2")
FOLDERS=("new" "tmp")
SCOPE_NAME="收件箱 (new、tmp)"
;;
"3"|"")
FOLDERS=("cur" "new" "tmp")
SCOPE_NAME="全部邮箱 (cur、new、tmp)"
;;
*)
red "错误:无效的清理范围选择!"
exit 1
;;
esac
if [[ -z "$cleanup_scope" ]]; then
green "您选择了:$SCOPE_NAME(默认)"
else
green "您选择了:$SCOPE_NAME"
fi
# 询问是否清理索引文件
echo ""
yellow "额外清理选项:"
echo "注意:以下文件是邮件索引文件,如果异常过大可以清理"
echo " 清理后Dovecot会自动重建,但用户可能需要重新登录邮件客户端"
echo -n "是否清理异常大的索引文件 (dovecot.*, maildirsize 等)?(Y/n,直接回车默认清理): "
read clean_index
if [[ "$clean_index" =~ ^[Nn]$ ]]; then
CLEAN_INDEX=false
echo "跳过索引文件清理"
else
CLEAN_INDEX=true
echo "将同时清理异常索引文件"
fi
# 索引文件清理阈值设置
if [ "$CLEAN_INDEX" = true ]; then
echo ""
blue "索引文件清理阈值设置:"
echo "1. 全部清理 (不管大小)"
echo "2. 中等模式 (大于50M)"
echo "3. 宽松模式 (大于100M)"
echo -n "请选择阈值 (直接回车默认1-全部清理): "
read threshold_choice
case "$threshold_choice" in
"1"|"")
INDEX_THRESHOLD=0
THRESHOLD_NAME="全部清理(所有大小)"
;;
"2")
INDEX_THRESHOLD=52428800 # 50M in bytes
THRESHOLD_NAME="中等模式(>50M)"
;;
"3")
INDEX_THRESHOLD=104857600 # 100M in bytes
THRESHOLD_NAME="宽松模式(>100M)"
;;
*)
red "错误:无效的阈值选择!使用默认值全部清理"
INDEX_THRESHOLD=0
THRESHOLD_NAME="全部清理(所有大小)"
;;
esac
green "索引清理阈值:$THRESHOLD_NAME"
fi
# 确认操作
echo ""
yellow "========================================"
echo "即将执行以下操作:"
echo "- 清理域名: ${SELECTED_DOMAINS[*]}"
echo "- 清理范围: $SCOPE_NAME"
if [ "$CLEAN_INDEX" = true ]; then
echo "- 索引清理: 是 ($THRESHOLD_NAME)"
fi
echo ""
red "注意:仅保护 /www/vmail 根目录下的数据库文件"
if [ -n "$ROOT_DB_FILES" ]; then
echo "受保护的根目录文件:"
echo "$ROOT_DB_FILES" | while read -r db_file; do
echo " 🔒 $db_file"
done
fi
yellow "========================================"
echo -n "确认开始清理吗?(Y/n,直接回车默认确认): "
read confirm
if [[ "$confirm" =~ ^[Nn]$ ]]; then
yellow "操作已取消"
exit 0
else
green "确认执行清理操作..."
fi
# 检查文件是否在根目录的保护列表中
is_root_protected() {
local file="$1"
local file_dir=$(dirname "$file")
# 如果文件在 /www/vmail 根目录,检查是否是数据库文件
if [ "$file_dir" = "$MAIL_BASE" ]; then
local filename=$(basename "$file")
case "$filename" in
*.db|*.sqlite|*.sqlite3|*.db-shm|*.db-wal|*.db-journal)
return 0 # 受保护
;;
esac
fi
return 1 # 不受保护
}
# 清理目录的函数
clean_directory() {
local dir="$1"
local cleaned=0
if [ ! -d "$dir" ]; then
echo 0
return
fi
# 统计文件数
local file_count=$(find "$dir" -type f 2>/dev/null | wc -l)
if [ $file_count -gt 0 ]; then
# 直接删除所有文件(因为域名目录内不需要保护)
find "$dir" -type f -delete 2>/dev/null
cleaned=$file_count
fi
echo $cleaned
}
# 清理索引文件的函数
clean_index_files() {
local user_dir="$1"
local cleaned_count=0
if [ ! -d "$user_dir" ]; then
return 0
fi
cd "$user_dir" 2>/dev/null || return 0
# 定义要清理的索引文件
local index_files=(
"dovecot-uidlist"
"dovecot-uidvalidity"
"dovecot-uidvalidity.*"
"dovecot.index*"
"dovecot.mailbox.log"
"maildirsize"
"subscriptions"
)
for pattern in "${index_files[@]}"; do
# 使用通配符匹配
for file in $pattern; do
if [ -f "$file" ]; then
local file_size=$(stat -c%s "$file" 2>/dev/null || echo 0)
if [ "$INDEX_THRESHOLD" = "0" ] || [ "$file_size" -gt "$INDEX_THRESHOLD" ]; then
local original_size=$(ls -lh "$file" | awk '{print $5}')
echo " 📁 清理索引: $file (${original_size})"
# 特殊处理 uidlist 文件
if [[ "$file" == "dovecot-uidlist" ]]; then
echo "3" > "$file" 2>/dev/null
else
truncate -s 0 "$file" 2>/dev/null || > "$file" 2>/dev/null
fi
cleaned_count=$((cleaned_count + 1))
fi
fi
done
done
return $cleaned_count
}
# 清理域名的函数
clean_domain() {
local domain="$1"
echo ""
blue "====== 开始清理域名: $domain ======"
local mail_base="/www/vmail/$domain"
if [ ! -d "$mail_base" ]; then
yellow "域名目录不存在: $mail_base"
return
fi
# 获取所有邮件账号
local mail_users=()
while IFS= read -r -d '' dir; do
local user=$(basename "$dir")
if [ -d "$dir" ] && [ "$user" != "$domain" ]; then
mail_users+=("$user")
fi
done < <(find "$mail_base" -maxdepth 1 -type d -print0 2>/dev/null | sort -z)
if [ ${#mail_users[@]} -eq 0 ]; then
yellow "在 $domain 下未找到任何邮箱账号"
return
fi
local total_cleaned=0
local total_index_cleaned=0
local total_accounts=0
local total_users=${#mail_users[@]}
local current_user=0
green "该域名下共有 $total_users 个邮箱账号需要处理"
echo "----------------------------------------"
for user in "${mail_users[@]}"; do
current_user=$((current_user + 1))
user_dir="$mail_base/$user"
# 显示进度
echo -ne "\r[$current_user/$total_users] 处理账号: $user ... "
# 检查目录是否可访问
if [ ! -d "$user_dir" ] || [ ! -r "$user_dir" ]; then
yellow "无法访问目录,跳过"
continue
fi
local user_cleaned=0
local user_index_cleaned=0
# 清理邮件文件夹
for folder in "${FOLDERS[@]}"; do
target_dir="$user_dir/$folder"
if [ -d "$target_dir" ] && [ -r "$target_dir" ]; then
cleaned=$(clean_directory "$target_dir")
user_cleaned=$((user_cleaned + cleaned))
fi
done
# 清理索引文件
if [ "$CLEAN_INDEX" = true ]; then
clean_index_files "$user_dir"
user_index_cleaned=$?
total_index_cleaned=$((total_index_cleaned + user_index_cleaned))
fi
if [ $user_cleaned -gt 0 ] || [ $user_index_cleaned -gt 0 ]; then
echo -e "\r[$current_user/$total_users] ✅ 账号: $user 完成 - 邮件: $user_cleaned, 索引: $user_index_cleaned"
else
echo -e "\r[$current_user/$total_users] ○ 账号: $user 无需清理"
fi
total_cleaned=$((total_cleaned + user_cleaned))
total_accounts=$((total_accounts + 1))
done
echo ""
green "✅ 域名 $domain 清理完成:"
echo " - 处理账号: $total_accounts 个"
[ $total_cleaned -gt 0 ] && echo " - 清理邮件: $total_cleaned 个文件"
[ "$CLEAN_INDEX" = true ] && [ $total_index_cleaned -gt 0 ] && echo " - 清理索引: $total_index_cleaned 个文件"
}
# 格式化时间函数
format_duration() {
local total_seconds=$1
local hours=$((total_seconds / 3600))
local minutes=$(( (total_seconds % 3600) / 60 ))
local seconds=$((total_seconds % 60))
if [ $hours -gt 0 ]; then
echo "${hours}小时${minutes}分钟${seconds}秒"
elif [ $minutes -gt 0 ]; then
echo "${minutes}分钟${seconds}秒"
else
echo "${seconds}秒"
fi
}
# 主清理流程
echo ""
green "开始清理操作..."
yellow "========================================"
# 停止邮件服务
echo "停止邮件服务..."
MAIL_START_TIME=$(date +%s)
# 检查 bt 命令是否存在
if command -v bt &> /dev/null; then
bt stop mail
else
# 尝试直接停止 dovecot 和 postfix
systemctl stop dovecot 2>/dev/null
systemctl stop postfix 2>/dev/null
service dovecot stop 2>/dev/null
service postfix stop 2>/dev/null
fi
# 等待服务完全停止
sleep 3
# 执行清理
TOTAL_DOMAINS=${#SELECTED_DOMAINS[@]}
CURRENT_DOMAIN=0
for domain in "${SELECTED_DOMAINS[@]}"; do
CURRENT_DOMAIN=$((CURRENT_DOMAIN + 1))
echo ""
yellow ">>> 正在处理域名 [$CURRENT_DOMAIN/$TOTAL_DOMAINS]: $domain"
DOMAIN_START_TIME=$(date +%s)
clean_domain "$domain"
DOMAIN_END_TIME=$(date +%s)
DOMAIN_DURATION=$((DOMAIN_END_TIME - DOMAIN_START_TIME))
green ">>> 域名 $domain 处理耗时: $(format_duration $DOMAIN_DURATION)"
echo "========================================"
done
# 重启邮件服务
echo ""
echo "重启邮件服务..."
if command -v bt &> /dev/null; then
bt start mail
else
systemctl start dovecot 2>/dev/null
systemctl start postfix 2>/dev/null
service dovecot start 2>/dev/null
service postfix start 2>/dev/null
fi
MAIL_END_TIME=$(date +%s)
MAIL_DURATION=$((MAIL_END_TIME - MAIL_START_TIME))
# 清理邮件阶段耗时
CLEAN_END_TIME=$(date +%s)
CLEAN_DURATION=$((CLEAN_END_TIME - START_TIME))
echo ""
green "=== 邮件清理操作完成 ==="
echo "清理范围: $SCOPE_NAME"
echo "处理域名: ${SELECTED_DOMAINS[*]}"
[ "$CLEAN_INDEX" = true ] && echo "索引清理: $THRESHOLD_NAME"
echo "邮件服务停止时间: $(format_duration $MAIL_DURATION)"
echo "邮件清理耗时: $(format_duration $CLEAN_DURATION)"
echo ""
# 询问是否清理系统日志
yellow "========================================"
echo -n "是否安全清理系统日志?可能占用很大 (y/N,直接回车默认不清理): "
read clean_logs
if [[ "$clean_logs" =~ ^[Yy]$ ]]; then
echo ""
green "开始清理系统日志..."
LOG_START_TIME=$(date +%s)
# 清理当前系统日志
echo "正在清理使用中的系统日志..."
truncate -s 0 /var/log/syslog 2>/dev/null || true
truncate -s 0 /var/log/messages 2>/dev/null || true
truncate -s 0 /var/log/maillog 2>/dev/null || true
green "✓ 安全清理使用中的日志完成"
# 清理压缩的旧日志文件
echo "正在清理备份的早期日志..."
find /var/log -name "*.gz" -o -name "*.bz2" -o -name "*.[0-9]" -delete 2>/dev/null || true
green "✓ 清理备份的早期日志完成"
# 清理宝塔日志
if [ -d "/www/server/panel/logs" ]; then
echo "正在清理宝塔面板日志..."
find /www/server/panel/logs -name "*.log" -exec truncate -s 0 {} \; 2>/dev/null || true
green "✓ 清理宝塔面板日志完成"
fi
LOG_END_TIME=$(date +%s)
LOG_DURATION=$((LOG_END_TIME - LOG_START_TIME))
green "系统日志清理完成!耗时: $(format_duration $LOG_DURATION)"
else
echo "跳过系统日志清理"
fi
# 显示磁盘使用情况
echo ""
yellow "========================================"
echo "当前磁盘使用情况:"
yellow "========================================"
df -h | awk '
NR==1 {
printf "%-20s %8s %8s %8s %6s %s\n", "文件系统", "容量", "已用", "可用", "已用%", "挂载点"
print "--------------------------------------------------------------------------------"
}
NR>1 {
printf "%-20s %8s %8s %8s %6s %s\n", $1, $2, $3, $4, $5, $6
}'
# 显示邮件目录空间
echo ""
yellow "邮件目录空间使用:"
if [ -d "/www/vmail" ]; then
echo "邮件目录总大小: $(du -sh /www/vmail 2>/dev/null | awk '{print $1}')"
echo ""
echo "各域名空间使用情况:"
du -sh /www/vmail/* 2>/dev/null | sort -hr | head -10
# 显示根目录数据库文件状态(确认没有被清理)
if [ -n "$ROOT_DB_FILES" ]; then
echo ""
green "根目录受保护的数据库文件状态:"
echo "$ROOT_DB_FILES" | while read -r db_file; do
if [ -f "$db_file" ]; then
size=$(ls -lh "$db_file" | awk '{print $5}')
echo " ✅ $db_file ($size)"
fi
done
fi
fi
# 计算总耗时
END_TIME=$(date +%s)
TOTAL_DURATION=$((END_TIME - START_TIME))
echo ""
green "========================================"
green "=== 所有操作完成 ==="
echo "总耗时: $(format_duration $TOTAL_DURATION)"
echo "完成时间: $(date '+%Y-%m-%d %H:%M:%S')"
green "========================================"
echo ""
echo "脚本执行完毕,可删除本文件: rm -f btmailclearpro.sh"