AI编程辅助工具:5个提升代码可用性的Prompt模板
2026/11/5 12:25:43
basename/eval),同时外接磁盘空间有限、多目录备份易出现同名冲突——更关键的是,恢复模式无图形界面、无法访问网络,无法直接复制粘贴脚本内容,这些问题都让备份变得棘手。本文将从实际踩坑经验出发,一步步构建完全适配恢复模式环境的备份脚本,实现「多目录批量备份+保留路径层级+排除指定目录+无外部命令依赖」的目标,同时提供「提前预置脚本」的实操流程和常见问题排查指南,附最终可直接运行的完整脚本。
在编写脚本前,需先明确恢复模式下的特殊限制:
basename、eval等常用命令可能不存在,且环境变量不完整,需用绝对路径调用系统命令;|| {}),函数定义/数组操作需严格遵循原生语法;我们需要实现的备份逻辑:
tar.gz并排除指定目录(如.git/node_modules);针对恢复模式的限制,需对脚本做针对性适配:
basename功能恢复模式中basename命令可能缺失,通过bash字符串截取实现路径最后一级的提取:
get_last_part(){localPATH_STR="$1"PATH_STR=${PATH_STR%/}# 去除末尾斜杠echo"${PATH_STR##*/}"# 截取最后一个斜杠后的内容}eval依赖:用数组传递tar排除参数恢复模式无eval命令,通过数组传递参数替代字符串拼接,直接传递给tar:
get_exclude_array(){localexclude_arr=()forDIRin".git""node_modules";doexclude_arr+=("--exclude=$DIR")doneecho"${exclude_arr[@]}"}# 调用示例localexclude_params=($(get_exclude_array))/usr/bin/tar zcfp"$TAR_FILE_PATH""${exclude_params[@]}""$SOURCE_ITEM"{前有空格,内部语句完整;|| {}),改用显式if/else判断;/bin/date//usr/bin/tar)。tar.gz文件;以下是适配所有恢复模式限制的无依赖备份脚本,已整合所有功能,可直接预置到备份磁盘:
#!/bin/bash# 配置项(已适配实际场景)EXCLUDE_DIRS=(".git""node_modules")BACKUP_TARGET_ROOT="/Volumes/S1/MyBackup"SOURCE_DIRS=("/Volumes/data/projects""/Volumes/soft/repos")# 检查目录存在check_dir_exists(){localDIR="$1"if[!-d"$DIR"];thenecho"错误:目录不存在 -$DIR"return1fireturn0}# 检查磁盘空间check_disk_space(){localDIR="$1"localFREE_SPACE=$(/bin/df -k"$DIR"|/usr/bin/tail -1|/usr/bin/awk'{print $4}')localMIN_SPACE=$((2048*1024))if!/usr/bin/echo"$FREE_SPACE"|/usr/bin/grep -q'^[0-9]*$';thenecho"警告:无法获取磁盘空间,跳过检查"return0fiif["$FREE_SPACE"-lt"$MIN_SPACE"];thenecho"错误:空间不足!可用$((FREE_SPACE/1024))MB,需2GB"exit1fiecho"磁盘空间检查通过,可用$((FREE_SPACE/1024))MB"}# 替代basenameget_last_part(){localPATH_STR="$1"PATH_STR=${PATH_STR%/}echo"${PATH_STR##*/}"}# 构建排除参数数组get_exclude_array(){localexclude_arr=()forDIRin"${EXCLUDE_DIRS[@]}";doexclude_arr+=("--exclude=$DIR")doneecho"${exclude_arr[@]}"}# 处理单个备份项process_source_item(){localSOURCE_ITEM="$1"localPARENT_SOURCE_DIR="$2"localPARENT_DIR_NAME=$(get_last_part"$PARENT_SOURCE_DIR")localITEM_NAME=$(get_last_part"$SOURCE_ITEM")localTIMESTAMP=$(/bin/date +%Y%m%d_%H%M%S)localBACKUP_SUB_DIR="$BACKUP_TARGET_ROOT/$PARENT_DIR_NAME"/bin/mkdir -p"$BACKUP_SUB_DIR"||{echo" 无法创建子目录";return1;}if[-f"$SOURCE_ITEM"];thenecho" 复制文件:$ITEM_NAME"/bin/cp -p"$SOURCE_ITEM""$BACKUP_SUB_DIR/"[$?-eq0]&&echo" 成功:$PARENT_DIR_NAME/$ITEM_NAME"||echo" 失败"elif[-d"$SOURCE_ITEM"];thenlocalTAR_FILE_NAME="${ITEM_NAME}_${TIMESTAMP}.tar.gz"localTAR_FILE_PATH="$BACKUP_SUB_DIR/$TAR_FILE_NAME"localexclude_params=($(get_exclude_array))echo" 打包目录:$ITEM_NAME->$TAR_FILE_NAME"/usr/bin/tar zcfp"$TAR_FILE_PATH""${exclude_params[@]}""$SOURCE_ITEM"if[$?-eq0];thenecho" 成功:$PARENT_DIR_NAME/$TAR_FILE_NAME"else[-f"$TAR_FILE_PATH"]&&/bin/rm -f"$TAR_FILE_PATH"echo" 失败"fielseecho" 跳过不支持的类型:$ITEM_NAME"fi}# 主流程echo"========================================"echo"macOS恢复模式备份脚本(最终版)"echo"执行时间:$(/bin/date"+%Y-%m-%d %H:%M:%S")"echo"备份目标:$BACKUP_TARGET_ROOT"echo"========================================"if!check_dir_exists"$BACKUP_TARGET_ROOT";thenecho"创建备份根目录:$BACKUP_TARGET_ROOT"/bin/mkdir -p"$BACKUP_TARGET_ROOT"||{echo"创建失败";exit1;}ficheck_disk_space"$BACKUP_TARGET_ROOT"localSOURCE_DIRforSOURCE_DIRin"${SOURCE_DIRS[@]}";doecho"----------------------------------------"if!check_dir_exists"$SOURCE_DIR";thenecho"跳过不存在的目录:$SOURCE_DIR"continuefilocalDIR_NAME=$(get_last_part"$SOURCE_DIR")echo"处理目录:$SOURCE_DIR"echo"备份层级:$BACKUP_TARGET_ROOT/$DIR_NAME"echo"----------------------------------------"/usr/bin/find"$SOURCE_DIR"-maxdepth1-mindepth1|whileread-r ITEM;doprocess_source_item"$ITEM""$SOURCE_DIR"donedoneecho"========================================"echo"备份完成!路径:$BACKUP_TARGET_ROOT"echo"========================================"exit0由于macOS恢复模式无网络访问、无图形界面剪贴板,无法直接复制粘贴脚本,需采用「提前预置脚本到备份磁盘」的方案,具体步骤如下:
S1)连接到电脑,确保磁盘为可写格式(APFS/ExFAT,避免NTFS只读);nano /Volumes/S1/backup_final.sh(直接在备份磁盘根目录创建脚本);BACKUP_TARGET_ROOT(已默认适配/Volumes/S1/MyBackup);Ctrl+O保存,Enter确认文件名,Ctrl+X退出nano;chmod +x /Volumes/S1/backup_final.sh;Command (⌘) + R直到出现Apple标志;S1),点击右上角「挂载」(若显示「已锁定」,先点击「解锁」并输入磁盘密码);cd /Volumes/S1(对应你的备份磁盘名称,可通过ls /Volumes查看所有挂载磁盘);ls,确认能看到backup_final.sh文件;./backup_final.sh(或绝对路径/Volumes/S1/backup_final.sh,避免路径问题);docker/k8s打包时间较长),执行完成后终端会提示「备份完成」;diskutil unmount /Volumes/S1,即可移除磁盘完成备份。在实操过程中,容易遇到以下问题,针对性解决方案如下:
^M,即\r),macOS bash无法识别;# 进入脚本所在目录(如/Volumes/S1)cd/Volumes/S1# 清理换行符并生成新脚本(backup_fixed.sh)tr-d'\r'<backup_final.sh>backup_fixed.sh# 赋予新脚本执行权限chmod+x backup_fixed.sh# 执行新脚本./backup_fixed.shdate/tar/find等命令)date→/bin/datetar→/usr/bin/tarfind→/usr/bin/findcp→/bin/cpwhich 命令名(如which tar),可查看命令的绝对路径。SOURCE_DIRS数组里的大型目录(如docker/k8s),先备份小型目录,清理磁盘后再备份大型目录;Macintosh HD),点击「解锁」,输入Mac登录密码,确保系统盘挂载为可写模式。docker镜像),tar打包需要大量时间,恢复模式终端无实时进度条;ps aux | grep backup_final.sh,确认脚本进程是否在运行;本文的备份脚本完全适配macOS恢复模式的bash 3.2环境,解决了命令缺失、语法限制、无复制粘贴等核心痛点,同时提供了详细的「提前预置脚本」实操流程和常见问题排查指南。无论是系统故障后的应急备份,还是日常恢复模式下的文件迁移,都能通过该脚本高效、安全地完成任务,备份结果保留原目录层级,无同名冲突,便于后续系统恢复后的文件还原。