文档首页> 云计算> 使用Shell脚本实现USB设备的挂载与文件复制

使用Shell脚本实现USB设备的挂载与文件复制

发布时间:2025-07-27 00:04       

Shell脚本实现USB设备自动挂载与文件复制 🔄


一、脚本设计思路

  1. 设备检测:通过 lsblk或 blkid识别USB设备
  2. 挂载处理:动态创建挂载点,支持NTFS/FAT32/exFAT
  3. 文件操作:增量复制、权限保留、日志记录
  4. 安全卸载:同步写入后卸载设备

二、完整脚本代码

#!/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 "$@"  

三、关键代码解析

  1. 设备检测 (detect_usb)

    lsblk -dno NAME,TRAN,RM | awk '$2=="usb" && $3=="1" {print "/dev/"$1}'  
    
    • TRAN="usb":过滤USB接口设备
    • RM="1":确认是可移动设备
    • 避免误挂载系统硬盘
  2. 智能挂载 (mount_usb)

    mount -o "rw,noatime,windows_names" -t ntfs /dev/sdb1 /mnt/usb/1654321000  
    
    • windows_names:NTFS禁止非法文件名(如 *?:
    • 时间戳挂载点:避免多次插入冲突
  3. 增量复制 (copy_files)

    rsync -ahv --progress --stats --exclude="System Volume Information"  
    
    • -a:归档模式(保留权限、时间戳)
    • -h:人类可读大小
    • --exclude:跳过Windows系统目录
  4. 安全卸载

    sync && umount /mnt/usb/1654321000  # sync确保数据写入磁盘  
    

四、使用指南

  1. 保存脚本

    sudo nano /usr/local/bin/usb-copier  
    sudo chmod +x /usr/local/bin/usb-copier  
    
  2. 创建必要目录

    sudo mkdir -p /mnt/usb /var/backups  
    sudo touch /var/log/usb_copier.log  
    
  3. 手动执行

    sudo usb-copier  # 插入USB后运行  
    
  4. 自动触发(可选)
    创建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 "异常退出! 已清理资源"  
}  

六、企业级扩展功能

  1. 加密设备支持
    # 检测LUKS加密  
    if cryptsetup isLuks "$usb_dev"; then  
        cryptdev="usb_$(basename $usb_dev)"  
        cryptsetup open "$usb_dev" "$cryptdev"  
        mount "/dev/mapper/$cryptdev" "$mount_point"  
    fi  
    
  2. 邮件通知