使用效果
- 在服务端上传备份脚本
- 在本地保存脚本
- 在moba创建macro:sh 本地脚本地址
- 执行一次macro的效果:通过ssh执行远端备份脚本,再拉取压缩包,下载完成后删除远端压缩包文件

服务器备份脚本.sh
#!/bin/sh
# [配置参考]
# 1. 提权免密 (假设脚本名为 backup.sh):
# 执行 sudo visudo,在末尾添加: 你的用户名 ALL=(ALL) NOPASSWD: /绝对路径/backup.sh
# 2. 解压命令: sudo tar -xzvf "压缩包名" -C / --overwrite
# --- 1. 自动识别环境 ---
# 如果是通过 sudo 运行的,取原用户名;否则取当前用户
if [ -n "$SUDO_USER" ]; then
CURRENT_USER="$SUDO_USER"
else
CURRENT_USER=$(whoami)
fi
# 获取脚本所在的绝对目录
SCRIPT_PATH=$(readlink -f "$0")
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
cd "$SCRIPT_DIR"
# --- 2. 定义变量 ---
# 文件名包含当前用户名和时间戳
FILE_NAME="${CURRENT_USER}_$(date +"%Y%m%d%H%M%S").tar.gz"
# 排除列表 (Trilium 专用排除,如果是纯通用备份可按需调整)
EXCLUDES="--exclude=*/trilium/data/backup --exclude=*/trilium/data/log --exclude=*.db-shm --exclude=*.db-wal"
# 打包目标 (包含脚本自身和业务目录)
TARGETS="$SCRIPT_PATH /www"
# --- 3. 执行压缩 ---
echo ">>> [User: $CURRENT_USER] Starting backup to $FILE_NAME ..."
# 使用 sudo 执行,-P 保留绝对路径
sudo tar -czvPf "$FILE_NAME" $EXCLUDES $TARGETS
# --- 4. 权限归还 (核心:通用化处理) ---
# 将生成的 root 权限文件交还给当前执行脚本的普通用户
# sudo chown "$CURRENT_USER":"$CURRENT_USER" "$FILE_NAME"
# --- 5. 显示结果 ---
FILE_SIZE=$(du -h "$FILE_NAME" | cut -f1)
echo ">>> Backup complete: $SCRIPT_DIR/$FILE_NAME"
echo ">>> File size: $FILE_SIZE"
本地moba调度脚本.sh
#!/bin/bash
# 在 MobaXterm 的 macro 录制命令:
# bash /drives/d/fileJob/1606atibm/2105oracle/instance-20210526-1342/bak/backupMobaSSHAuto.sh
#!/bin/bash
echo "----------------"
echo "请确保已经 apt-get install -y connect-proxy"
echo "----------------"
# ==============================================
# 配置区 (所有的控制开关都在这里)
# ==============================================
REMOTE_USER="ghost"
REMOTE_HOST="arm.atibm.com"
KEY_PATH="/drives/d/fileJob/1606atibm/2105oracle/instance-20260324-ARM4C/ssh.key.20250215.oracle.ghost/oracle-rsa-ghost-nopsw"
LOCAL_DEST="/drives/d/fileJob/1606atibm/2105oracle/instance-20260324-ARM4C/bak"
REMOTE_SH="/home/ghost/backupGhost.sh"
TMP_OUTPUT="/tmp/backup_output.txt"
# --- 代理配置 ---
USE_PROXY=true # ❗ 开关
PROXY_BIN="/usr/bin/connect-proxy"
PROXY_ADDR="127.0.0.1:7890" # ❗ 以后改端口只改这里
# --- 颜色定义 ---
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_time() { echo -e "${BLUE}[$(date +'%H:%M:%S')]${NC} $1"; }
# ==============================================
# 0. 环境预检
# ==============================================
log_time "${YELLOW}任务启动: 远程备份与同步${NC}"
echo "----------------------------------------------"
echo -e "远程主机: ${GREEN}$REMOTE_USER@$REMOTE_HOST${NC}"
echo -e "本地路径: ${GREEN}$LOCAL_DEST${NC}"
echo -e "代理状态: $( [ "$USE_PROXY" = true ] && echo -e "${GREEN}开启 ($PROXY_ADDR)${NC}" || echo -e "${RED}关闭${NC}" )"
echo "----------------------------------------------"
# ==============================================
# 1. 执行远程备份
# ==============================================
log_time "正在连接远程执行备份脚本..."
# 基础 SSH 参数
SSH_ARGS=(-x -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=15 -i "$KEY_PATH")
if [ "$USE_PROXY" = true ]; then
# 构造 ProxyCommand
PROXY_CMD="$PROXY_BIN -S $PROXY_ADDR %h %p"
# ❗ 修复:必须把代理参数加入数组
SSH_ARGS+=(-o "ProxyCommand=$PROXY_CMD")
fi
set -o pipefail
ssh "${SSH_ARGS[@]}" "$REMOTE_USER@$REMOTE_HOST" "sudo -n $REMOTE_SH" 2>&1 | tee "$TMP_OUTPUT"
SSH_STATUS=$?
if [ $SSH_STATUS -ne 0 ]; then
echo -e "\n${RED}[错误] 远程备份失败 (Exit Code: $SSH_STATUS)${NC}"
exit 1
fi
# ==============================================
# 2. 提取备份路径
# ==============================================
log_time "分析备份日志..."
REMOTE_FILE=$(grep "Backup complete:" "$TMP_OUTPUT" | awk '{print $NF}' | tr -d '\r')
if [ -z "$REMOTE_FILE" ]; then
echo -e "${RED}[错误] 无法提取路径!${NC}"
tail -n 5 "$TMP_OUTPUT"
exit 1
fi
FILE_BASENAME=$(basename "$REMOTE_FILE")
echo -e "最新备份: ${GREEN}$FILE_BASENAME${NC}"
# ==============================================
# 3. 下载文件 (rsync)
# ==============================================
log_time "准备下载文件..."
# 构造 rsync 专用的 SSH 字符串
RSYNC_SSH_CMD="ssh -i $KEY_PATH -o BatchMode=yes -o StrictHostKeyChecking=no"
if [ "$USE_PROXY" = true ]; then
# 使用变量 $PROXY_ADDR
RSYNC_SSH_CMD="$RSYNC_SSH_CMD -o \"ProxyCommand=$PROXY_BIN -S $PROXY_ADDR %h %p\""
fi
# 执行 rsync
rsync -avz --progress -e "$RSYNC_SSH_CMD" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_FILE" "$LOCAL_DEST/"
RSYNC_STATUS=$?
# ==============================================
# 4. 完成与清理
# ==============================================
if [ $RSYNC_STATUS -eq 0 ]; then
echo -e "\n${GREEN}>>> [下载成功]${NC} 文件保存至: $LOCAL_DEST/$FILE_BASENAME"
log_time "正在清理远程临时文件..."
# 清理阶段也使用相同的 SSH 代理配置
ssh "${SSH_ARGS[@]}" "$REMOTE_USER@$REMOTE_HOST" "sudo -n rm -f $REMOTE_FILE"
rm -f "$TMP_OUTPUT"
echo -e "----------------------------------------------"
echo -e "${GREEN}★ 任务全部完成! ★${NC}"
else
echo -e "\n${RED}[错误] rsync 下载失败 (Code: $RSYNC_STATUS)${NC}"
exit 1
fi
解压
- sudo tar -xzvpf ghost20250701090751.tar.gz -C /
- -x: 解压
- -z: 处理 gzip
- -v: 显示进度
- -f: 指定文件
- -p: 关键参数!保留原始文件的权限、所有者和时间戳
- -C: 指定解压到/