|
@@ -1,20 +1,838 @@
|
|
|
#!/bin/bash
|
|
#!/bin/bash
|
|
|
-#此脚本用于将downloads目录下最新的ppt拷贝到u盘,并弹出u盘
|
|
|
|
|
-
|
|
|
|
|
-# 获取U盘路径
|
|
|
|
|
-usb_path="/run/media/nonvioce/U盘"
|
|
|
|
|
-
|
|
|
|
|
-# 检查是否有U盘插入
|
|
|
|
|
-if [ -d "$usb_path" ]; then
|
|
|
|
|
- # 获取Downloads文件夹中的所有文件
|
|
|
|
|
- files=$(ls /home/nonvioce/Downloads)
|
|
|
|
|
-
|
|
|
|
|
- # 找到最新的文件
|
|
|
|
|
- latest_file=$(ls -t /home/nonvioce/Downloads | head -n1)
|
|
|
|
|
- echo $latest_file
|
|
|
|
|
- # 将最新的文件复制到U盘
|
|
|
|
|
- cp /home/nonvioce/Downloads/$latest_file "$usb_path"
|
|
|
|
|
- umount /run/media/nonvioce/U盘
|
|
|
|
|
|
|
+set -euo pipefail
|
|
|
|
|
+
|
|
|
|
|
+# copyfast — 快速拷贝最新文件到绑定的U盘
|
|
|
|
|
+#
|
|
|
|
|
+# 模式:
|
|
|
|
|
+# (无参数) 正常模式: 找到绑定的U盘, 拷贝最新匹配文件并弹出
|
|
|
|
|
+# --count N 指定拷贝最新的 N 个文件 (默认1)
|
|
|
|
|
+# --no-unmount 拷贝后不弹出U盘
|
|
|
|
|
+# --bind 绑定当前插入的U盘 (自动选最大分区, 可绑定多个)
|
|
|
|
|
+# --unbind 解除已绑定的U盘
|
|
|
|
|
+# --install-udev 安装 udev 规则, 插入U盘时自动运行
|
|
|
|
|
+# --uninstall-udev 移除 udev 规则
|
|
|
|
|
+# --config 打印当前配置
|
|
|
|
|
+# --help 帮助信息
|
|
|
|
|
+
|
|
|
|
|
+# 真实用户检测: sudo → $SUDO_USER, 否则 → $USER, --user 可覆盖
|
|
|
|
|
+# 真实 HOME 根据最终 REAL_USER 推导
|
|
|
|
|
+_resolve_home() {
|
|
|
|
|
+ getent passwd "$1" 2>/dev/null | cut -d: -f6
|
|
|
|
|
+}
|
|
|
|
|
+if [[ -n "${SUDO_USER:-}" ]]; then
|
|
|
|
|
+ REAL_USER="$SUDO_USER"
|
|
|
|
|
+ REAL_HOME="$(_resolve_home "$SUDO_USER")"
|
|
|
else
|
|
else
|
|
|
- echo "U盘未插入"
|
|
|
|
|
|
|
+ REAL_USER="$USER"
|
|
|
|
|
+ REAL_HOME="$HOME"
|
|
|
fi
|
|
fi
|
|
|
|
|
+
|
|
|
|
|
+CONFIG_DIR="${XDG_CONFIG_HOME:-$REAL_HOME/.config}/copyfast"
|
|
|
|
|
+CONFIG_FILE="$CONFIG_DIR/config"
|
|
|
|
|
+SCRIPT_PATH="$(realpath "$0")"
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 默认配置
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+SOURCE_DIR="$REAL_HOME/Downloads"
|
|
|
|
|
+EXTENSIONS="" # 逗号分隔, 空=所有文件
|
|
|
|
|
+USB_UUIDS="" # 绑定的U盘UUID列表 (空格分隔)
|
|
|
|
|
+AUTO_UNMOUNT="true" # 拷贝后自动弹出 (默认开启)
|
|
|
|
|
+FILE_COUNT="1" # 拷贝最新文件的数量
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 加载配置
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+load_config() {
|
|
|
|
|
+ if [[ -f "$CONFIG_FILE" ]]; then
|
|
|
|
|
+ source "$CONFIG_FILE"
|
|
|
|
|
+ fi
|
|
|
|
|
+ # 迁移旧格式: USB_UUID → USB_UUIDS
|
|
|
|
|
+ if [[ -z "$USB_UUIDS" ]] && [[ -n "${USB_UUID:-}" ]]; then
|
|
|
|
|
+ USB_UUIDS="$USB_UUID"
|
|
|
|
|
+ save_config
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 保存配置
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+save_config() {
|
|
|
|
|
+ mkdir -p "$CONFIG_DIR"
|
|
|
|
|
+ cat > "$CONFIG_FILE" <<EOF
|
|
|
|
|
+# copyfast 配置文件
|
|
|
|
|
+# 由 copyfast --bind / --unbind 写入, 也可手动编辑
|
|
|
|
|
+
|
|
|
|
|
+SOURCE_DIR="$SOURCE_DIR"
|
|
|
|
|
+EXTENSIONS="$EXTENSIONS"
|
|
|
|
|
+USB_UUIDS="$USB_UUIDS"
|
|
|
|
|
+AUTO_UNMOUNT="$AUTO_UNMOUNT"
|
|
|
|
|
+FILE_COUNT="$FILE_COUNT"
|
|
|
|
|
+EOF
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 将USB_UUIDS字符串转为数组
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+get_bound_uuids() {
|
|
|
|
|
+ local -a result=()
|
|
|
|
|
+ if [[ -n "$USB_UUIDS" ]]; then
|
|
|
|
|
+ for uuid in $USB_UUIDS; do
|
|
|
|
|
+ [[ -n "$uuid" ]] && result+=("$uuid")
|
|
|
|
|
+ done
|
|
|
|
|
+ fi
|
|
|
|
|
+ echo "${result[@]:-}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 列出当前插入的USB设备 — 每磁盘只返回最大分区
|
|
|
|
|
+# 输出格式: DISK_NAME|UUID|LABEL|MOUNTPOINT|SIZE
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+list_usb_disks() {
|
|
|
|
|
+ # 获取USB磁盘名称
|
|
|
|
|
+ local usb_disks
|
|
|
|
|
+ usb_disks=$(lsblk -o NAME,TRAN -d -l -n 2>/dev/null | awk '$2=="usb"{print $1}')
|
|
|
|
|
+ [[ -z "$usb_disks" ]] && return
|
|
|
|
|
+
|
|
|
|
|
+ for disk in $usb_disks; do
|
|
|
|
|
+ # 获取此磁盘下的分区
|
|
|
|
|
+ local parts best_uuid best_label best_mp best_size_bytes best_size_str
|
|
|
|
|
+ local part_size_bytes part_size_str part_uuid part_label part_mp
|
|
|
|
|
+ best_size_bytes=0
|
|
|
|
|
+
|
|
|
|
|
+ local parts_list
|
|
|
|
|
+ parts_list=$(lsblk -o NAME -l -n "/dev/$disk" 2>/dev/null | grep -v "^$disk\$")
|
|
|
|
|
+ while IFS= read -r part; do
|
|
|
|
|
+ local dev="/dev/$part"
|
|
|
|
|
+ part_uuid=$(lsblk -o UUID -n "$dev" | tr -d '[:space:]')
|
|
|
|
|
+ [[ -z "$part_uuid" ]] && continue
|
|
|
|
|
+ part_size_str=$(lsblk -o SIZE -n "$dev" | tr -d '[:space:]')
|
|
|
|
|
+ part_label=$(lsblk -o LABEL -n "$dev" | tr -d '[:space:]')
|
|
|
|
|
+ part_mp=$(lsblk -o MOUNTPOINT -n "$dev" | tr -d '[:space:]')
|
|
|
|
|
+
|
|
|
|
|
+ # 解析 SIZE
|
|
|
|
|
+ local unit val
|
|
|
|
|
+ unit="${part_size_str: -1}"
|
|
|
|
|
+ val="${part_size_str%?}"
|
|
|
|
|
+ case "$unit" in
|
|
|
|
|
+ T) part_size_bytes=$((val * 1099511627776)) ;;
|
|
|
|
|
+ G) part_size_bytes=$((val * 1073741824)) ;;
|
|
|
|
|
+ M) part_size_bytes=$((val * 1048576)) ;;
|
|
|
|
|
+ K) part_size_bytes=$((val * 1024)) ;;
|
|
|
|
|
+ *) part_size_bytes=$val ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "$part_size_bytes" -gt "$best_size_bytes" ]]; then
|
|
|
|
|
+ best_size_bytes=$part_size_bytes
|
|
|
|
|
+ best_uuid=$part_uuid
|
|
|
|
|
+ best_label=$part_label
|
|
|
|
|
+ best_mp=$part_mp
|
|
|
|
|
+ best_size_str=$part_size_str
|
|
|
|
|
+ fi
|
|
|
|
|
+ done <<< "$parts_list"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -n "${best_uuid:-}" ]]; then
|
|
|
|
|
+ echo "$disk|$best_uuid|${best_label:-}|${best_mp:-}|${best_size_str:-}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ done
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 通过UUID查找设备 (不管是否挂载)
|
|
|
|
|
+# 返回 "MOUNTPOINT|KNAME" 或 "|KNAME" (未挂载时挂载点为空)
|
|
|
|
|
+# 通过 /dev/disk/by-uuid/ 和 lsblk 单列输出, 避免空列解析问题
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+find_device_by_uuid() {
|
|
|
|
|
+ local uuid="$1"
|
|
|
|
|
+ local dev_path
|
|
|
|
|
+
|
|
|
|
|
+ # 优先使用 udev 直接传递的设备路径 (避免 /dev/disk/by-uuid 未就绪)
|
|
|
|
|
+ if [[ -n "${UDEV_DEVICE:-}" ]] && [[ -e "$UDEV_DEVICE" ]]; then
|
|
|
|
|
+ dev_path="$UDEV_DEVICE"
|
|
|
|
|
+ else
|
|
|
|
|
+ dev_path="/dev/disk/by-uuid/$uuid"
|
|
|
|
|
+ [[ -e "$dev_path" ]] || { return 1; }
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local mp k
|
|
|
|
|
+ mp=$(lsblk -o MOUNTPOINT -n "$dev_path" | head -1 | tr -d '[:space:]')
|
|
|
|
|
+ k=$(basename "$(readlink -f "$dev_path")")
|
|
|
|
|
+
|
|
|
|
|
+ echo "$mp|$k"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 挂载设备, 返回挂载点
|
|
|
|
|
+# 多级保底: root直接用mount, 普通用户用udisksctl
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+mount_device() {
|
|
|
|
|
+ local uuid="$1"
|
|
|
|
|
+ local dev_path
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -n "${UDEV_DEVICE:-}" ]] && [[ -e "$UDEV_DEVICE" ]]; then
|
|
|
|
|
+ dev_path="$UDEV_DEVICE"
|
|
|
|
|
+ else
|
|
|
|
|
+ dev_path="/dev/disk/by-uuid/$uuid"
|
|
|
|
|
+ [[ -e "$dev_path" ]] || return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 已挂载则直接返回挂载点
|
|
|
|
|
+ local mp
|
|
|
|
|
+ mp=$(lsblk -o MOUNTPOINT -n "$dev_path" 2>/dev/null | head -1 | tr -d '[:space:]')
|
|
|
|
|
+ if [[ -n "$mp" ]]; then
|
|
|
|
|
+ echo "$mp"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 尝试1: udisksctl (需要D-Bus会话, 适用于桌面环境)
|
|
|
|
|
+ if udisksctl mount -b "$dev_path" 2>/dev/null; then
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 尝试2: root 直接 mount (适用于udev触发场景)
|
|
|
|
|
+ if [[ "$(id -u)" == "0" ]]; then
|
|
|
|
|
+ local mnt="/run/media/copyfast/$uuid"
|
|
|
|
|
+ mkdir -p "$mnt"
|
|
|
|
|
+ if mount "$dev_path" "$mnt" 2>/dev/null; then
|
|
|
|
|
+ echo "$mnt"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 尝试3: sudo mount
|
|
|
|
|
+ local mnt="/run/media/copyfast/$uuid"
|
|
|
|
|
+ mkdir -p "$mnt" 2>/dev/null || true
|
|
|
|
|
+ if sudo mount "$dev_path" "$mnt" 2>/dev/null; then
|
|
|
|
|
+ echo "$mnt"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ return 1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 获取挂载点 (设备可能已挂载或需挂载)
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+get_mountpoint() {
|
|
|
|
|
+ local uuid="$1"
|
|
|
|
|
+ local dev_info
|
|
|
|
|
+ dev_info=$(find_device_by_uuid "$uuid")
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -z "$dev_info" ]]; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local mp="${dev_info%%|*}"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -z "$mp" ]]; then
|
|
|
|
|
+ if [[ "${UDEV_MODE:-false}" == "true" ]]; then
|
|
|
|
|
+ # udev模式: 不挂载, 等待桌面环境自动挂载 (最长10秒)
|
|
|
|
|
+ local i
|
|
|
|
|
+ for i in {1..10}; do
|
|
|
|
|
+ sleep 1
|
|
|
|
|
+ dev_info=$(find_device_by_uuid "$uuid")
|
|
|
|
|
+ mp="${dev_info%%|*}"
|
|
|
|
|
+ [[ -n "$mp" ]] && break
|
|
|
|
|
+ done
|
|
|
|
|
+ else
|
|
|
|
|
+ # 正常模式: 主动挂载
|
|
|
|
|
+ mount_device "$uuid" > /dev/null 2>&1 || return 1
|
|
|
|
|
+ sleep 1
|
|
|
|
|
+ dev_info=$(find_device_by_uuid "$uuid")
|
|
|
|
|
+ mp="${dev_info%%|*}"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -n "$mp" ]]; then
|
|
|
|
|
+ echo "$mp"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ return 1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 获取源目录中最新的 N 个文件 (每行一个路径)
|
|
|
|
|
+# $1: 源目录, $2: 逗号分隔的扩展名 (空=所有文件), $3: 数量 (默认1)
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+get_latest_files() {
|
|
|
|
|
+ local src="$1"
|
|
|
|
|
+ local exts="$2"
|
|
|
|
|
+ local count="${3:-1}"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ ! -d "$src" ]]; then
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -z "$exts" ]]; then
|
|
|
|
|
+ find "$src" -maxdepth 1 -type f -printf '%T@ %p\n' 2>/dev/null \
|
|
|
|
|
+ | sort -rn | head -n "$count" | cut -d' ' -f2-
|
|
|
|
|
+ return
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local IFS=','
|
|
|
|
|
+ local args=()
|
|
|
|
|
+ local ext_count=0
|
|
|
|
|
+ for ext in $exts; do
|
|
|
|
|
+ ext=$(echo "$ext" | tr -d '[:space:]')
|
|
|
|
|
+ [[ -z "$ext" ]] && continue
|
|
|
|
|
+ if [[ $ext_count -gt 0 ]]; then
|
|
|
|
|
+ args+=(-o)
|
|
|
|
|
+ fi
|
|
|
|
|
+ args+=(-iname "*.$ext")
|
|
|
|
|
+ ext_count=$((ext_count+1))
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ if [[ $ext_count -eq 0 ]]; then
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ $ext_count -gt 1 ]]; then
|
|
|
|
|
+ find "$src" -maxdepth 1 -type f \( "${args[@]}" \) -printf '%T@ %p\n' 2>/dev/null \
|
|
|
|
|
+ | sort -rn | head -n "$count" | cut -d' ' -f2-
|
|
|
|
|
+ else
|
|
|
|
|
+ find "$src" -maxdepth 1 -type f "${args[@]}" -printf '%T@ %p\n' 2>/dev/null \
|
|
|
|
|
+ | sort -rn | head -n "$count" | cut -d' ' -f2-
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 日志 (udev触发时写入logger, 否则写入stderr)
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+log() {
|
|
|
|
|
+ if [[ "${UDEV_MODE:-false}" == "true" ]]; then
|
|
|
|
|
+ logger -t "copyfast" "$@"
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "$@" >&2
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 桌面通知 (通过 real user 的 D-Bus)
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+_notify() {
|
|
|
|
|
+ local uid
|
|
|
|
|
+ uid=$(id -u "$REAL_USER" 2>/dev/null) || { log "通知: 无法获取用户UID"; return 0; }
|
|
|
|
|
+
|
|
|
|
|
+ local bus="/run/user/$uid/bus"
|
|
|
|
|
+ if [[ ! -S "$bus" ]]; then
|
|
|
|
|
+ log "通知: D-Bus 会话总线不可用 ($bus)"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ export DBUS_SESSION_BUS_ADDRESS="unix:path=$bus"
|
|
|
|
|
+
|
|
|
|
|
+ # 尝试多种方式获取 DISPLAY
|
|
|
|
|
+ if [[ -z "${DISPLAY:-}" ]]; then
|
|
|
|
|
+ # 从 loginctl 获取用户会话的 display
|
|
|
|
|
+ local display
|
|
|
|
|
+ display=$(loginctl show-user "$REAL_USER" -p Display 2>/dev/null | cut -d= -f2)
|
|
|
|
|
+ # 兜底: 常见的 display 值
|
|
|
|
|
+ for d in "${display:-}" ":0" ":1"; do
|
|
|
|
|
+ [[ -z "$d" ]] && continue
|
|
|
|
|
+ export DISPLAY="$d"
|
|
|
|
|
+ break
|
|
|
|
|
+ done
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if notify-send -i drive-removable-media "copyfast" "$*" -t 5000 2>/dev/null; then
|
|
|
|
|
+ log "通知: 桌面通知已发送"
|
|
|
|
|
+ else
|
|
|
|
|
+ log "通知: notify-send 执行失败"
|
|
|
|
|
+ fi
|
|
|
|
|
+ return 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 正常模式: 查找USB并拷贝最新文件
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+do_copy() {
|
|
|
|
|
+ if [[ -z "$USB_UUIDS" ]]; then
|
|
|
|
|
+ log "错误: 未绑定U盘。请先插入U盘并运行: $(basename "$0") --bind"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ ! "$FILE_COUNT" =~ ^[1-9][0-9]*$ ]]; then
|
|
|
|
|
+ log "错误: 文件数量不是有效的正整数: $FILE_COUNT"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 遍历已绑定UUID, 找到第一个可用的
|
|
|
|
|
+ log "正在查找已绑定的U盘..."
|
|
|
|
|
+ local uuids uuid mountpoint was_mounted
|
|
|
|
|
+ uuids=($(get_bound_uuids))
|
|
|
|
|
+
|
|
|
|
|
+ for uuid in "${uuids[@]}"; do
|
|
|
|
|
+ # 检查设备是否存在
|
|
|
|
|
+ local dev_info
|
|
|
|
|
+ dev_info=$(find_device_by_uuid "$uuid")
|
|
|
|
|
+ [[ -z "$dev_info" ]] && continue
|
|
|
|
|
+
|
|
|
|
|
+ local current_mp="${dev_info%%|*}"
|
|
|
|
|
+ was_mounted="$current_mp"
|
|
|
|
|
+
|
|
|
|
|
+ mountpoint=$(get_mountpoint "$uuid" 2>/dev/null) || {
|
|
|
|
|
+ log "警告: 无法挂载 UUID=$uuid, 尝试下一个..."
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ break
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -z "${mountpoint:-}" ]]; then
|
|
|
|
|
+ log "错误: 未找到任何已绑定的U盘, 请确认U盘已插入"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ log "找到已绑定U盘: UUID=$uuid, 挂载点=$mountpoint"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ ! -d "$SOURCE_DIR" ]]; then
|
|
|
|
|
+ log "错误: 源目录不存在: $SOURCE_DIR"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ log "正在 $SOURCE_DIR 中查找最新 $FILE_COUNT 个文件..."
|
|
|
|
|
+ local files
|
|
|
|
|
+ files=$(get_latest_files "$SOURCE_DIR" "$EXTENSIONS" "$FILE_COUNT")
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -z "$files" ]]; then
|
|
|
|
|
+ if [[ -n "$EXTENSIONS" ]]; then
|
|
|
|
|
+ log "错误: 未在 $SOURCE_DIR 中找到匹配扩展名 ($EXTENSIONS) 的文件"
|
|
|
|
|
+ else
|
|
|
|
|
+ log "错误: $SOURCE_DIR 中没有文件"
|
|
|
|
|
+ fi
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local copied=0
|
|
|
|
|
+ while IFS= read -r f; do
|
|
|
|
|
+ [[ -z "$f" ]] && continue
|
|
|
|
|
+ log "拷贝 ($((copied+1))/$FILE_COUNT): $(basename "$f") -> $mountpoint"
|
|
|
|
|
+ cp "$f" "$mountpoint/"
|
|
|
|
|
+ copied=$((copied+1))
|
|
|
|
|
+ done <<< "$files"
|
|
|
|
|
+
|
|
|
|
|
+ log "拷贝完成: 共 $copied 个文件 -> $mountpoint"
|
|
|
|
|
+
|
|
|
|
|
+ # udev模式下发送桌面通知
|
|
|
|
|
+ if [[ "${UDEV_MODE:-false}" == "true" ]]; then
|
|
|
|
|
+ _notify "拷贝完成: 共 $copied 个文件"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "$AUTO_UNMOUNT" == "true" ]]; then
|
|
|
|
|
+ log "正在弹出U盘..."
|
|
|
|
|
+
|
|
|
|
|
+ # udev模式下设置 D-Bus 环境以便 udisksctl 工作
|
|
|
|
|
+ if [[ "${UDEV_MODE:-false}" == "true" ]]; then
|
|
|
|
|
+ local uid
|
|
|
|
|
+ uid=$(id -u "$REAL_USER" 2>/dev/null)
|
|
|
|
|
+ if [[ -n "${uid:-}" ]] && [[ -S "/run/user/$uid/bus" ]]; then
|
|
|
|
|
+ export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$uid/bus"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local dev_to_unmount="${UDEV_DEVICE:-/dev/disk/by-uuid/$uuid}"
|
|
|
|
|
+ if udisksctl unmount -b "$dev_to_unmount" 2>/dev/null; then
|
|
|
|
|
+ log "已弹出U盘 (unmount)"
|
|
|
|
|
+ elif udisksctl power-off -b "$dev_to_unmount" 2>/dev/null; then
|
|
|
|
|
+ log "已弹出U盘 (power-off)"
|
|
|
|
|
+ elif umount "$mountpoint" 2>/dev/null; then
|
|
|
|
|
+ log "已弹出U盘 (umount)"
|
|
|
|
|
+ elif sudo umount "$mountpoint" 2>/dev/null; then
|
|
|
|
|
+ log "已弹出U盘 (sudo umount)"
|
|
|
|
|
+ else
|
|
|
|
|
+ log "警告: 弹出 $mountpoint 失败 (可能有其他程序正在使用)"
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 绑定模式: 自动选择每个U盘的最大分区, 加入绑定列表
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+do_bind() {
|
|
|
|
|
+ local devices
|
|
|
|
|
+ devices=$(list_usb_disks)
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -z "$devices" ]]; then
|
|
|
|
|
+ echo "错误: 未检测到插入的USB设备, 请先插入U盘"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local disk uuid label mp size
|
|
|
|
|
+
|
|
|
|
|
+ # 收集当前已绑定的UUID
|
|
|
|
|
+ local -A bound_map
|
|
|
|
|
+ if [[ -n "$USB_UUIDS" ]]; then
|
|
|
|
|
+ for bid in $USB_UUIDS; do
|
|
|
|
|
+ bound_map["$bid"]=1
|
|
|
|
|
+ done
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 过滤掉已绑定的, 收集可绑定的
|
|
|
|
|
+ local candidates=()
|
|
|
|
|
+ while IFS='|' read -r disk uuid label mp size; do
|
|
|
|
|
+ if [[ -n "${bound_map[$uuid]:-}" ]]; then
|
|
|
|
|
+ echo "跳过已绑定: $uuid (标签=${label:-(无)}, 挂载点=${mp:-(未挂载)})"
|
|
|
|
|
+ continue
|
|
|
|
|
+ fi
|
|
|
|
|
+ candidates+=("$disk|$uuid|$label|$mp|$size")
|
|
|
|
|
+ done <<< "$devices"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ ${#candidates[@]} -eq 0 ]]; then
|
|
|
|
|
+ echo "所有已插入的U盘都已绑定。"
|
|
|
|
|
+ echo "当前绑定: $USB_UUIDS"
|
|
|
|
|
+ echo "如需解绑, 请运行: $(basename "$0") --unbind"
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local chosen_uuid chosen_label chosen_disk
|
|
|
|
|
+ local count=${#candidates[@]}
|
|
|
|
|
+
|
|
|
|
|
+ if [[ "$count" -eq 1 ]]; then
|
|
|
|
|
+ IFS='|' read -r chosen_disk chosen_uuid chosen_label _ _ <<< "${candidates[0]}"
|
|
|
|
|
+ echo "检测到1个新U盘, 自动选择最大分区:"
|
|
|
|
|
+ echo " 磁盘: $chosen_disk"
|
|
|
|
|
+ echo " 标签: ${chosen_label:-(无)}"
|
|
|
|
|
+ echo " UUID: $chosen_uuid"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "检测到 $count 个新U盘, 请选择要绑定的设备:"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ local i=1
|
|
|
|
|
+ local lines=()
|
|
|
|
|
+ for cand in "${candidates[@]}"; do
|
|
|
|
|
+ IFS='|' read -r disk uuid label mp size <<< "$cand"
|
|
|
|
|
+ echo " [$i] 磁盘=$disk 标签=${label:-(无)} UUID=$uuid 挂载点=${mp:-(未挂载)}"
|
|
|
|
|
+ lines+=("$cand")
|
|
|
|
|
+ ((i++))
|
|
|
|
|
+ done
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ read -rp "请选择要绑定的编号 [1-$count]: " choice
|
|
|
|
|
+ if [[ ! "$choice" =~ ^[0-9]+$ ]] || [[ "$choice" -lt 1 ]] || [[ "$choice" -gt "$count" ]]; then
|
|
|
|
|
+ echo "错误: 无效选择"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ IFS='|' read -r chosen_disk chosen_uuid chosen_label _ _ <<< "${lines[$((choice-1))]}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 添加到绑定列表
|
|
|
|
|
+ if [[ -z "$USB_UUIDS" ]]; then
|
|
|
|
|
+ USB_UUIDS="$chosen_uuid"
|
|
|
|
|
+ else
|
|
|
|
|
+ USB_UUIDS="$USB_UUIDS $chosen_uuid"
|
|
|
|
|
+ fi
|
|
|
|
|
+ save_config
|
|
|
|
|
+
|
|
|
|
|
+ echo "已绑定U盘:"
|
|
|
|
|
+ echo " 磁盘: $chosen_disk"
|
|
|
|
|
+ echo " 标签: ${chosen_label:-(无)}"
|
|
|
|
|
+ echo " UUID: $chosen_uuid"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "当前所有绑定: $USB_UUIDS"
|
|
|
|
|
+ echo "配置已保存到 $CONFIG_FILE"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "后续可直接运行 $(basename "$0") 或安装 udev 规则以实现自动运行:"
|
|
|
|
|
+ echo " $(basename "$0") --install-udev"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 解绑模式: 交互选择已绑定的U盘并移除
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+do_unbind() {
|
|
|
|
|
+ if [[ -z "$USB_UUIDS" ]]; then
|
|
|
|
|
+ echo "当前没有绑定的U盘。"
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local uuids
|
|
|
|
|
+ uuids=($USB_UUIDS)
|
|
|
|
|
+
|
|
|
|
|
+ echo "当前绑定列表:"
|
|
|
|
|
+ local i=1
|
|
|
|
|
+ for uuid in "${uuids[@]}"; do
|
|
|
|
|
+ # 查询标签信息
|
|
|
|
|
+ local info
|
|
|
|
|
+ info=$(lsblk -o UUID,LABEL,MOUNTPOINT -l -n 2>/dev/null | awk -v u="$uuid" '$1==u {print "标签=" $2 " 挂载点=" $3}')
|
|
|
|
|
+ echo " [$i] UUID=$uuid ${info:-未插入}"
|
|
|
|
|
+ ((i++))
|
|
|
|
|
+ done
|
|
|
|
|
+ echo ""
|
|
|
|
|
+
|
|
|
|
|
+ if [[ ${#uuids[@]} -eq 1 ]]; then
|
|
|
|
|
+ read -rp "确认解除此绑定? [y/N]: " confirm
|
|
|
|
|
+ if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
|
|
|
|
+ echo "已取消"
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+ USB_UUIDS=""
|
|
|
|
|
+ else
|
|
|
|
|
+ read -rp "请选择要解除的编号 [1-${#uuids[@]}] (留空取消): " choice
|
|
|
|
|
+ if [[ -z "$choice" ]]; then
|
|
|
|
|
+ echo "已取消"
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+ if [[ ! "$choice" =~ ^[1-9][0-9]*$ ]] || [[ "$choice" -gt "${#uuids[@]}" ]]; then
|
|
|
|
|
+ echo "错误: 无效选择"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ unset 'uuids[$((choice-1))]'
|
|
|
|
|
+ USB_UUIDS="${uuids[*]}"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ save_config
|
|
|
|
|
+ echo "已解除绑定。"
|
|
|
|
|
+ if [[ -n "$USB_UUIDS" ]]; then
|
|
|
|
|
+ echo "当前绑定: $USB_UUIDS"
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "当前没有任何绑定。"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 安装 udev 规则 — 为每个已绑定UUID生成一条规则
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+do_install_udev() {
|
|
|
|
|
+ if [[ -z "$USB_UUIDS" ]]; then
|
|
|
|
|
+ echo "错误: 尚未绑定U盘, 请先运行: $(basename "$0") --bind"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local udev_rule="/etc/udev/rules.d/99-copyfast.rules"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ -f "$udev_rule" ]]; then
|
|
|
|
|
+ echo "udev 规则已存在于 $udev_rule"
|
|
|
|
|
+ read -rp "是否覆盖? [y/N]: " confirm
|
|
|
|
|
+ if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
|
|
|
|
+ echo "已取消"
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+ sudo rm "$udev_rule"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ echo "正在生成 udev 规则..."
|
|
|
|
|
+
|
|
|
|
|
+ local uuids
|
|
|
|
|
+ uuids=($USB_UUIDS)
|
|
|
|
|
+
|
|
|
|
|
+ {
|
|
|
|
|
+ echo "# copyfast udev rules — 插入已绑定U盘时自动运行"
|
|
|
|
|
+ echo "# 安装时间: $(date)"
|
|
|
|
|
+ for uuid in "${uuids[@]}"; do
|
|
|
|
|
+ echo "ACTION==\"add\", SUBSYSTEM==\"block\", ENV{ID_FS_UUID}==\"$uuid\", RUN+=\"/usr/bin/systemd-run --uid=$REAL_USER --gid=$(id -g "$REAL_USER") --collect -- $SCRIPT_PATH --udev-triggered --device /dev/\$kernel\""
|
|
|
|
|
+ done
|
|
|
|
|
+ } | sudo tee "$udev_rule" > /dev/null
|
|
|
|
|
+
|
|
|
|
|
+ echo "正在重新加载 udev 规则..."
|
|
|
|
|
+ sudo udevadm control --reload-rules
|
|
|
|
|
+ sudo udevadm trigger
|
|
|
|
|
+
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "udev 规则安装完成: $udev_rule"
|
|
|
|
|
+ echo "已为 ${#uuids[@]} 个U盘生成规则。"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "规则内容:"
|
|
|
|
|
+ cat "$udev_rule"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "现在插入任意已绑定的U盘, 脚本将自动运行。"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 卸载 udev 规则
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+do_uninstall_udev() {
|
|
|
|
|
+ local udev_rule="/etc/udev/rules.d/99-copyfast.rules"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ ! -f "$udev_rule" ]]; then
|
|
|
|
|
+ echo "udev 规则不存在: $udev_rule"
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ echo "正在移除 udev 规则..."
|
|
|
|
|
+ sudo rm "$udev_rule"
|
|
|
|
|
+
|
|
|
|
|
+ echo "正在重新加载 udev 规则..."
|
|
|
|
|
+ sudo udevadm control --reload-rules
|
|
|
|
|
+
|
|
|
|
|
+ echo "已移除 udev 规则。"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 打印配置
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+do_config() {
|
|
|
|
|
+ echo "当前配置:"
|
|
|
|
|
+ echo " 配置文件: $CONFIG_FILE"
|
|
|
|
|
+ echo " 源目录: $SOURCE_DIR"
|
|
|
|
|
+ echo " 文件后缀: ${EXTENSIONS:-(所有文件)}"
|
|
|
|
|
+ echo " 拷贝数量: 最新的 $FILE_COUNT 个文件"
|
|
|
|
|
+ echo " 拷贝后弹出: $AUTO_UNMOUNT"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ if [[ -z "$USB_UUIDS" ]]; then
|
|
|
|
|
+ echo " 已绑定U盘: (无)"
|
|
|
|
|
+ else
|
|
|
|
|
+ echo " 已绑定U盘 ($(echo "$USB_UUIDS" | wc -w) 个):"
|
|
|
|
|
+ local uuids
|
|
|
|
|
+ uuids=($USB_UUIDS)
|
|
|
|
|
+ for uuid in "${uuids[@]}"; do
|
|
|
|
|
+ local info
|
|
|
|
|
+ info=$(lsblk -o UUID,LABEL,MOUNTPOINT -l -n 2>/dev/null \
|
|
|
|
|
+ | awk -v u="$uuid" '$1==u {printf "标签=%s, 挂载点=%s", ($2?$2:"无"), ($3?$3:"未挂载")}')
|
|
|
|
|
+ echo " UUID=$uuid ${info:-未插入}"
|
|
|
|
|
+ done
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 帮助
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+do_help() {
|
|
|
|
|
+ cat <<HELP
|
|
|
|
|
+copyfast — 从指定目录快速拷贝最新文件到绑定的U盘
|
|
|
|
|
+
|
|
|
|
|
+用法: $(basename "$0") [选项]
|
|
|
|
|
+
|
|
|
|
|
+正常使用:
|
|
|
|
|
+ 直接运行即可将 SOURCE_DIR 中最新的 FILE_COUNT 个匹配文件
|
|
|
|
|
+ 拷贝到已绑定的U盘 (第一个检测到的), 拷贝完成后自动弹出U盘。
|
|
|
|
|
+
|
|
|
|
|
+选项:
|
|
|
|
|
+ -n, --count N 拷贝最新的 N 个文件 (默认: 1)
|
|
|
|
|
+ 例: $(basename "$0") --count 3
|
|
|
|
|
+ -N, --no-unmount 拷贝后不弹出U盘
|
|
|
|
|
+ 例: $(basename "$0") --no-unmount
|
|
|
|
|
+
|
|
|
|
|
+绑定与管理:
|
|
|
|
|
+ -b, --bind 绑定当前插入的U盘到配置文件
|
|
|
|
|
+ 每个U盘只选最大分区, 可重复执行绑定多个U盘
|
|
|
|
|
+ 例: $(basename "$0") --bind
|
|
|
|
|
+ -u, --unbind 解除已绑定的U盘, 交互选择要移除的绑定
|
|
|
|
|
+ 例: $(basename "$0") --unbind
|
|
|
|
|
+ -i, --install-udev 安装 udev 规则 (需 sudo 权限)
|
|
|
|
|
+ 为所有已绑定U盘生成规则, 插入任意一个即自动运行
|
|
|
|
|
+ -U, --uninstall-udev 移除 udev 规则 (需 sudo 权限)
|
|
|
|
|
+ -c, --config 打印当前所有配置项及其值
|
|
|
|
|
+ -h, --help 显示此帮助信息
|
|
|
|
|
+
|
|
|
|
|
+配置文件: $CONFIG_FILE
|
|
|
|
|
+ 配置项说明:
|
|
|
|
|
+ SOURCE_DIR 要拷贝哪个目录下的最新文件
|
|
|
|
|
+ 默认: ~/Downloads
|
|
|
|
|
+ EXTENSIONS 只拷贝这些后缀的文件, 逗号分隔, 大小写不敏感
|
|
|
|
|
+ 留空表示所有文件
|
|
|
|
|
+ 例: "ppt,pptx,pdf" 或 "zip,tar.gz,7z"
|
|
|
|
|
+ FILE_COUNT 每次拷贝最新的几个文件, 必须是正整数 (默认1)
|
|
|
|
|
+ USB_UUIDS 绑定的U盘UUID列表 (空格分隔), 由 --bind/--unbind 维护
|
|
|
|
|
+ 请不要手动修改此项
|
|
|
|
|
+ AUTO_UNMOUNT 拷贝后是否自动弹出U盘
|
|
|
|
|
+ true=弹出 (默认), false=不弹出
|
|
|
|
|
+ 命令行 --no-unmount 可临时覆盖为不弹出
|
|
|
|
|
+
|
|
|
|
|
+使用示例:
|
|
|
|
|
+ # 首次配置
|
|
|
|
|
+ $(basename "$0") --bind # 插入U盘后绑定 (自动选最大分区)
|
|
|
|
|
+ $(basename "$0") --count 3 # 拷贝最新3个文件到U盘
|
|
|
|
|
+ $(basename "$0") --no-unmount # 拷贝但不弹出
|
|
|
|
|
+
|
|
|
|
|
+ # 管理多个U盘
|
|
|
|
|
+ $(basename "$0") --bind # 插入另一个U盘, 再次绑定
|
|
|
|
|
+ $(basename "$0") --config # 查看所有绑定
|
|
|
|
|
+ $(basename "$0") --unbind # 解除某个绑定
|
|
|
|
|
+
|
|
|
|
|
+ # 修改默认行为: 编辑配置文件
|
|
|
|
|
+ # 将 EXTENSIONS 设为 "ppt,pptx" 则之后只拷贝这两种文件
|
|
|
|
|
+ # 将 FILE_COUNT 设为 "5" 则之后每次拷贝5个文件
|
|
|
|
|
+
|
|
|
|
|
+ # 安装自动运行后, 插入任意已绑定U盘自动拷贝并弹出
|
|
|
|
|
+ $(basename "$0") --install-udev
|
|
|
|
|
+
|
|
|
|
|
+技术说明:
|
|
|
|
|
+ - USB设备通过文件系统UUID识别, 不受挂载点路径变化影响
|
|
|
|
|
+ - 每个U盘只选最大分区, 避免绑定到启动分区等小分区
|
|
|
|
|
+ - 支持绑定多个不同U盘, 运行时使用最先检测到的那个
|
|
|
|
|
+ - udev模式下轮询等待挂载 (最长10秒), 日志写入 syslog
|
|
|
|
|
+ - 文件匹配使用 find -iname, 扩展名匹配不区分大小写
|
|
|
|
|
+HELP
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 入口与参数解析
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+
|
|
|
|
|
+# 先加载配置文件, 后续命令行参数可覆盖配置值
|
|
|
|
|
+load_config
|
|
|
|
|
+
|
|
|
|
|
+UDEV_MODE=false
|
|
|
|
|
+UDEV_DEVICE=""
|
|
|
|
|
+
|
|
|
|
|
+# 使用 while+shift 解析参数, 支持 --count N 这种带值参数
|
|
|
|
|
+while [[ $# -gt 0 ]]; do
|
|
|
|
|
+ case "$1" in
|
|
|
|
|
+ --udev-triggered)
|
|
|
|
|
+ UDEV_MODE=true
|
|
|
|
|
+ shift
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --user)
|
|
|
|
|
+ if [[ -z "${2:-}" ]] || [[ "${2:0:1}" == "-" ]]; then
|
|
|
|
|
+ echo "错误: --user 需要指定用户名"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ REAL_USER="$2"
|
|
|
|
|
+ REAL_HOME="$(_resolve_home "$2")"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --device)
|
|
|
|
|
+ if [[ -z "${2:-}" ]] || [[ "${2:0:1}" == "-" ]]; then
|
|
|
|
|
+ echo "错误: --device 需要指定设备路径"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ UDEV_DEVICE="$2"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --count|-n)
|
|
|
|
|
+ if [[ -z "${2:-}" ]] || [[ "${2:0:1}" == "-" ]]; then
|
|
|
|
|
+ echo "错误: --count 需要指定一个正整数"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ FILE_COUNT="$2"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --no-unmount|-N)
|
|
|
|
|
+ AUTO_UNMOUNT="false"
|
|
|
|
|
+ shift
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --bind|-b)
|
|
|
|
|
+ do_bind
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --unbind|-u)
|
|
|
|
|
+ do_unbind
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --install-udev|-i)
|
|
|
|
|
+ do_install_udev
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --uninstall-udev|-U)
|
|
|
|
|
+ do_uninstall_udev
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --config|-c)
|
|
|
|
|
+ do_config
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --help|-h)
|
|
|
|
|
+ do_help
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ *)
|
|
|
|
|
+ echo "错误: 未知选项 '$1'"
|
|
|
|
|
+ echo "运行 $(basename "$0") --help 查看用法"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+done
|
|
|
|
|
+
|
|
|
|
|
+# 进入正常拷贝模式
|
|
|
|
|
+# 注意: udev 模式下由 systemd-run 管理生命周期, 无需后台化
|
|
|
|
|
+do_copy
|