使用Shell脚本实现USB设备的挂载与文件复制
发布时间:2025-07-27 00:04       
Shell脚本实现USB设备自动挂载与文件复制 🔄
一、脚本设计思路
- 设备检测:通过
lsblk
或blkid
识别USB设备 - 挂载处理:动态创建挂载点,支持NTFS/FAT32/exFAT
- 文件操作:增量复制、权限保留、日志记录
- 安全卸载:同步写入后卸载设备
二、完整脚本代码
#!/bin/bash
# USB自动挂载与文件复制工具
# 作者:YourName 版本:1.2
# 🔧 配置区 =================================
TARGET_DIR="/mnt/usb" # 挂载点基础路径
BACKUP_DIR="/var/backups" # 本地备份目录
LOG_FILE="/var/log/usb_copier.log" # 操作日志路径
ALLOW_FS="vfat ntfs exfat ext4" # 支持的文件系统
# 📌 函数:日志记录
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 🔍 检测USB设备
detect_usb() {
# 查找可移动设备且非系统盘
usb_dev=$(lsblk -dno NAME,TRAN,RM | awk '$2=="usb" && $3=="1" {print "/dev/"$1}')
[ -z "$usb_dev" ] && {
log "未检测到USB设备"
exit 1
}
log "检测到USB设备: $usb_dev"
echo "$usb_dev"
}
# 🖥️ 挂载USB设备
mount_usb() {
dev_path="$1"
fs_type=$(blkid -o value -s TYPE "$dev_path" 2>/dev/null)
# 验证文件系统
if ! grep -q "$fs_type" <<< "$ALLOW_FS"; then
log "不支持的文件系统: $fs_type"
exit 2
fi
# 创建动态挂载点
mount_point="${TARGET_DIR}/$(date +%s)"
mkdir -p "$mount_point" || {
log "挂载点创建失败: $mount_point"
exit 3
}
# 挂载参数
mount_opts="rw,noatime"
[ "$fs_type" = "ntfs" ] && mount_opts+=",windows_names"
# 执行挂载
mount -o "$mount_opts" -t "$fs_type" "$dev_path" "$mount_point" && {
log "挂载成功: $dev_path → $mount_point"
echo "$mount_point"
} || {
log "挂载失败! 错误码: $?"
rm -rf "$mount_point"
exit 4
}
}
# 📂 文件复制操作
copy_files() {
src_dir="$1"
rsync -ahv --progress --stats \
--log-file="$LOG_FILE" \
--exclude="System Volume Information" \
"$src_dir/" "$BACKUP_DIR/"
return $?
}
# ⚙️ 主流程
main() {
usb_dev=$(detect_usb)
mount_point=$(mount_usb "$usb_dev")
log "开始复制文件..."
if copy_files "$mount_point"; then
log "文件复制完成! 共复制: $(du -sh $BACKUP_DIR | cut -f1)"
else
log "复制失败! 错误码: $?"
fi
# 安全卸载
umount "$mount_point" && rm -rf "$mount_point"
log "设备已卸载"
}
# 🚀 执行入口
main "$@"
三、关键代码解析
-
设备检测 (
detect_usb
)lsblk -dno NAME,TRAN,RM | awk '$2=="usb" && $3=="1" {print "/dev/"$1}'
TRAN="usb"
:过滤USB接口设备RM="1"
:确认是可移动设备- 避免误挂载系统硬盘
-
智能挂载 (
mount_usb
)mount -o "rw,noatime,windows_names" -t ntfs /dev/sdb1 /mnt/usb/1654321000
windows_names
:NTFS禁止非法文件名(如*?:
)- 时间戳挂载点:避免多次插入冲突
-
增量复制 (
copy_files
)rsync -ahv --progress --stats --exclude="System Volume Information"
-a
:归档模式(保留权限、时间戳)-h
:人类可读大小--exclude
:跳过Windows系统目录
-
安全卸载
sync && umount /mnt/usb/1654321000 # sync确保数据写入磁盘
四、使用指南
-
保存脚本:
sudo nano /usr/local/bin/usb-copier sudo chmod +x /usr/local/bin/usb-copier
-
创建必要目录:
sudo mkdir -p /mnt/usb /var/backups sudo touch /var/log/usb_copier.log
-
手动执行:
sudo usb-copier # 插入USB后运行
-
自动触发(可选):
创建udev规则/etc/udev/rules.d/99-usb-backup.rules
:ACTION=="add", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", RUN+="/usr/local/bin/usb-copier"
重载规则:
sudo udevadm control --reload
五、错误处理增强
在 main()
函数中添加异常捕获:
main() {
trap 'cleanup' EXIT INT TERM # 捕获退出信号
...
}
cleanup() {
# 强制卸载残留挂载点
grep -q "$TARGET_DIR" /proc/mounts && \
umount -l "$mount_point"
[ -d "$mount_point" ] && rm -rf "$mount_point"
log "异常退出! 已清理资源"
}
六、企业级扩展功能
- 加密设备支持:
# 检测LUKS加密 if cryptsetup isLuks "$usb_dev"; then cryptdev="usb_$(basename $usb_dev)" cryptsetup open "$usb_dev" "$cryptdev" mount "/dev/mapper/$cryptdev" "$mount_point" fi
- 邮件通知: