Bash部署脚本风险规避:避免挂载失败误删本地文件的方法
安全的远程文件部署Bash脚本流程
要彻底避免挂载异常时误删本地目录的风险,核心是从路径、验证、异常拦截三个层面锁死危险操作的执行条件,具体流程如下:
一、前置准备:隔离挂载环境
- 创建专用的空挂载目录(比如
/mnt/deploy_remote),绝对禁止使用当前工作目录或已有业务文件的目录。 - 脚本启动时先检查该目录:
- 若已被挂载,先执行卸载(
fusermount -u 挂载点); - 若目录非空,直接退出脚本,避免残留内容干扰。
- 若已被挂载,先执行卸载(
二、挂载远程目录:强制验证挂载状态
- 执行
sshfs挂载命令后,必须通过两种方式验证挂载成功:- 用
mountpoint -q 挂载点检查目录是否为有效挂载点; - 验证远程目录的唯一标记文件(比如提前在远程目录放置
.remote_deploy_marker),若无法读取该文件,判定挂载异常。
- 用
- 任何验证失败时,立即卸载挂载点并退出脚本,绝不执行后续删除/复制操作。
三、清理远程目录:使用绝对路径+精准排除
- 绝对禁止使用相对路径(比如
rm -rf ./*),必须用挂载点的绝对路径指定清理范围,比如/mnt/deploy_remote/*。 - 推荐用
rsync的删除模式替代rm,更安全且易控制排除规则:
该命令会删除挂载点下除指定文件外的所有内容,且仅作用于挂载的远程目录。rsync --delete-excluded --exclude='保留文件1' --exclude='保留文件2' /dev/null /mnt/deploy_remote/
四、文件复制:用rsync替代cp并校验结果
- 使用
rsync进行文件同步,它会在挂载中断时返回非0退出码,方便脚本捕获异常:rsync -avz --delete /本地目录/ /mnt/deploy_remote/ - 同步完成后检查
rsync的退出码,若不为0则判定同步失败,执行卸载并退出。
五、异常兜底:脚本全局防护
- 脚本开头添加
set -euo pipefail,让脚本在任何命令失败、变量未定义或管道错误时立即退出,阻止危险命令继续执行。 - 添加陷阱命令,确保脚本无论正常结束还是异常退出,都会尝试卸载挂载点:
trap 'fusermount -u /mnt/deploy_remote 2>/dev/null' EXIT
示例脚本片段
#!/bin/bash set -euo pipefail # 配置参数 LOCAL_DIR="/path/to/local/deploy_files" REMOTE_TARGET="user@remote.server:/remote/deploy_dir" MOUNT_POINT="/mnt/deploy_remote" # 需保留的远程文件列表 KEEP_FILES=(".remote_marker" "app_config.ini") # 检查并初始化挂载点 if [ -d "$MOUNT_POINT" ]; then mountpoint -q "$MOUNT_POINT" && fusermount -u "$MOUNT_POINT" [ "$(ls -A "$MOUNT_POINT")" ] && { echo "挂载点非空,退出"; exit 1; } else mkdir -p "$MOUNT_POINT" fi # 挂载远程目录 sshfs "$REMOTE_TARGET" "$MOUNT_POINT" # 双重验证挂载有效性 if ! mountpoint -q "$MOUNT_POINT" || [ ! -f "$MOUNT_POINT/${KEEP_FILES[0]}" ]; then echo "挂载失败或异常,清理退出" fusermount -u "$MOUNT_POINT" exit 1 fi # 清理远程目录 rsync --delete-excluded ${KEEP_FILES[@]/#/--exclude=''} /dev/null "$MOUNT_POINT/" # 同步本地文件 rsync -avz --delete "$LOCAL_DIR/" "$MOUNT_POINT/" # 卸载挂载点 fusermount -u "$MOUNT_POINT" echo "部署完成"
内容的提问来源于stack exchange,提问作者OZ1SEJ
相关产品推荐
相关产品推荐

