Files
tms-bbt-config-pkg/tms-bbt-config/usb_disk_fix_script.sh
2026-01-02 03:54:30 +08:00

140 lines
5.6 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
DEV_PATH="$1"
LOG_FILE="/var/log/usb_disk_fix.log" # 用于调试和记录所有输出
# 确保日志文件存在且可写
touch "$LOG_FILE"
chmod 644 "$LOG_FILE" # 确保普通用户可读,方便查看
# --- 辅助函数:同时输出到终端和日志文件 ---
# 所有重要的信息都通过这个函数输出
log_and_print() {
local message="$1"
echo "$(date): $message" | tee -a "$LOG_FILE"
}
# --- 辅助函数:执行命令并将其输出同时记录到终端和日志文件 ---
execute_and_log_output() {
local description="$1"
local command_to_run="$2"
log_and_print "Initiating command: $description"
log_and_print "Executing: $command_to_run"
# 执行命令,将其标准输出和标准错误都通过 tee 同时发送到终端和日志文件
# 注意:这里移除了后台运行的 '&' 符号,使命令同步执行
eval "$command_to_run" 2>&1 | tee -a "$LOG_FILE"
log_and_print "Command for '$description' finished."
}
# --- 主要逻辑 ---
log_and_print "Script started for $DEV_PATH"
# 1. 验证输入设备路径
if ! [ -b "$DEV_PATH" ]; then
log_and_print "$DEV_PATH 不是一个块设备。退出。"
exit 0
fi
# 2. 检查文件系统类型是否为 ext2 或 ext3
FS_TYPE=$(blkid -s TYPE -o value "$DEV_PATH" 2>/dev/null)
if [[ "$FS_TYPE" != "ext2" && "$FS_TYPE" != "ext3" ]]; then
log_and_print "$DEV_PATH 不是EXT2或EXT3文件系统 (类型: $FS_TYPE)。退出。"
exit 0
fi
# 3. 检查是否已经挂载
if findmnt -M "$DEV_PATH" &>/dev/null; then
log_and_print "$DEV_PATH 已经挂载。GVfs 或其他已处理。退出。"
exit 0
fi
# 4. 尝试临时挂载以检测是否能正常挂载
TEMP_MOUNT_DIR=$(mktemp -d)
log_and_print "Attempting temporary mount of $DEV_PATH to $TEMP_MOUNT_DIR"
MOUNT_OUTPUT=$(mount "$DEV_PATH" "$TEMP_MOUNT_DIR" 2>&1)
MOUNT_STATUS=$?
if [ "$MOUNT_STATUS" -eq 0 ]; then
# 挂载成功说明没有问题GVfs 应该能处理
umount "$TEMP_MOUNT_DIR"
rmdir "$TEMP_MOUNT_DIR"
log_and_print "$DEV_PATH 成功临时挂载。GVfs 将处理。退出。"
exit 0
else
# 挂载失败,尝试进行修复
log_and_print "$DEV_PATH 无法挂载。尝试进行修复 (fsck 和 resize2fs -f)。"
# 构建修复命令字符串
REPAIR_COMMAND="
echo \"$(date): 检测到USB磁盘 ($DEV_PATH) 无法挂载。尝试进行文件系统修复。\"
# 第一次文件系统检查
echo \"$(date): 正在进行文件系统检查 (fsck -fy) 第一次尝试...\"
# 使用 yes | 确保所有交互式提示都回答 'yes'
FSCK_OUTPUT_1=\$(yes | fsck -fy '$DEV_PATH' 2>&1)
FS_CHECK_STATUS_1=\$?
echo \"$(date): 第一次 fsck 输出 (状态码: \$FS_CHECK_STATUS_1):\"
echo \"\$FSCK_OUTPUT_1\"
local initial_fsck_had_errors=false
if [ \$FS_CHECK_STATUS_1 -ne 0 ]; then
echo \"$(date): WARNING: 第一次文件系统检查 (fsck) 发现错误。继续尝试 resize2fs。\"
initial_fsck_had_errors=true
else
echo \"$(date): 第一次文件系统检查 (fsck) 成功完成。\"
fi
# 强制调整文件系统大小
echo \"$(date): 正在强制调整文件系统大小 (resize2fs -f)...这可能需要一些时间。\"
RESIZE_OUTPUT=\$(resize2fs -f '$DEV_PATH' 2>&1)
RESIZE_STATUS=\$?
echo \"$(date): resize2fs 输出 (状态码: \$RESIZE_STATUS):\"
echo \"\$RESIZE_OUTPUT\"
if [ \$RESIZE_STATUS -ne 0 ]; then
echo \"$(date): ERROR: 文件系统修复 (resize2fs -f) 失败。请手动检查。\"
exit 1
else
echo \"$(date): 文件系统修复 (resize2fs -f) 完成!\"
fi
# *** 关键修改:修复后不再自己挂载,而是通过 udisksctl 触发桌面环境挂载 ***
echo \"$(date): 尝试通过 udisksctl 挂载磁盘,让桌面环境接管...\"
# 注意udisksctl 必须以原始用户身份运行,而不是 root
if [ -n \"\$SUDO_USER\" ]; then
UDISKS_MOUNT_OUTPUT=\$(sudo -u \"\$SUDO_USER\" udisksctl mount -b \"\$DEV_PATH\" 2>&1)
UDISKS_MOUNT_STATUS=\$?
else
# 如果没有 SUDO_USER (例如直接以 root 运行),则尝试直接 udisksctl mount
# 这在桌面环境下可能不理想,但作为备用方案
echo \"$(date): 警告:未检测到 SUDO_USER 变量,尝试直接以当前用户身份运行 udisksctl。\"
UDISKS_MOUNT_OUTPUT=\$(udisksctl mount -b \"\$DEV_PATH\" 2>&1)
UDISKS_MOUNT_STATUS=\$?
fi
if [ \$UDISKS_MOUNT_STATUS -eq 0 ]; then
echo \"$(date): USB磁盘 (\$DEV_PATH) 修复后成功通过 udisksctl 挂载!桌面环境将接管。\"
# 由于 udisksctl 会挂载到它自己的位置,我们不需要卸载 TEMP_MOUNT_DIR
# TEMP_MOUNT_DIR 应该保持为空,并在脚本结束时被 rmdir 清理
else
echo \"$(date): ERROR: USB磁盘 (\$DEV_PATH) 修复后通过 udisksctl 挂载失败。请手动检查。\"
echo \"udisksctl mount output: \$UDISKS_MOUNT_OUTPUT\"
exit 1
fi
echo \"$(date): 修复流程结束。\"
"
# 执行修复命令,所有输出都将记录到 LOG_FILE 并打印到终端
execute_and_log_output "USB磁盘修复 - $DEV_PATH" "$REPAIR_COMMAND"
# 清理临时挂载点(无论修复成功与否,只要它存在且为空)
# 在修复成功的情况下TEMP_MOUNT_DIR 应该没有被实际使用,所以是空的
if [ -d "$TEMP_MOUNT_DIR" ]; then
rmdir "$TEMP_MOUNT_DIR" 2>/dev/null
fi
exit 0
fi