TG推送效果

教程

复制脚本内容并更改(见文章最下)

给脚本设置权限

chmod +x backup.sh

申请密钥 实现免密传文件到另一台服务器

申请密钥 一路回车即可

ssh-keygen -t ecdsa -b 521

导入公钥到另一台vps

ssh-copy-id -i ~/.ssh/id_ecdsa.pub -p 服务器端口 root@服务器IP地址

如果是导入自己的密钥 请给私钥设置可读权限

chmod 600 .ssh/id_ecdsa

设置定时任务

crontab -e

每天0点执行备份

0 0 * * * /root/backup.sh

自动备份脚本

#!/bin/bash
 
# 配置部分:需要修改的内容
LOCAL_DIR="/path/to/dir"     # 需要备份的本地目录
REMOTE_USER="root"           # 远程 VPS 的用户名,默认 root
REMOTE_HOST="127.0.0.1"      # 远程 VPS 的域名或 IP 地址
REMOTE_PORT=""               # 远程 SSH 端口号,默认 22
REMOTE_DIR="/path/to/dir"    # 远程备份存储的目录
 
# Telegram 配置
BOT_TOKEN="your_bot_token"   # 替换为你的 Telegram 机器人 Token
CHAT_ID="your_chat_id"       # 替换为你的 Telegram Chat ID
 
# 设置 SCP 和 SSH 命令(根据端口号)
if [ -z "$REMOTE_PORT" ]; then
  SCP_CMD="scp"
  SSH_CMD="ssh"
else
  SCP_CMD="scp -P $REMOTE_PORT"
  SSH_CMD="ssh -p $REMOTE_PORT"
fi
 
# 备份文件名中包含的日期格式(使用北京时间)
TZ='Asia/Shanghai'
DATE=$(date +%Y-%m-%d_%H-%M)  # 格式化日期为:2025-01-22_14-30
LOCAL_HOSTNAME=$(hostname)    # 获取当前主机名
 
# 检查指定的备份目录是否存在
if [ ! -d "$LOCAL_DIR" ]; then
  MESSAGE="备份失败:目录 \`$LOCAL_DIR\` 不存在!%0A时间:\`$DATE\`"
  echo "备份失败:目录 $LOCAL_DIR 不存在!"
  if ! curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
    -d chat_id="$CHAT_ID" \
    -d text="$MESSAGE" \
    -d parse_mode="MarkdownV2" > /dev/null 2>&1; then
    echo "Telegram 消息发送失败,请检查 BOT_TOKEN 和 CHAT_ID 是否正确。"
  fi
  exit 1
fi
 
# 提取输入目录的最后一个子目录名称
LAST_DIR_NAME=$(basename "$LOCAL_DIR")
 
# 创建备份文件名
BACKUP_NAME="backup_${LOCAL_HOSTNAME}_${LAST_DIR_NAME}_${DATE}.tar.gz"
 
# 创建备份文件,备份最后一个子目录
tar -czf "$BACKUP_NAME" -C "$(dirname "$LOCAL_DIR")" "$LAST_DIR_NAME" > /dev/null 2>&1
 
# 确保备份文件创建成功
if [ ! -f "$BACKUP_NAME" ]; then
  MESSAGE="备份失败:无法创建备份文件!%0A时间:\`$DATE\`"
  echo "备份失败:无法创建备份文件!"
  if ! curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
    -d chat_id="$CHAT_ID" \
    -d text="$MESSAGE" \
    -d parse_mode="MarkdownV2" > /dev/null 2>&1; then
    echo "Telegram 消息发送失败,请检查 BOT_TOKEN 和 CHAT_ID 是否正确。"
  fi
  exit 1
fi
 
# 获取远程服务器的主机名
REMOTE_HOSTNAME=$($SSH_CMD $REMOTE_USER@$REMOTE_HOST "hostname" 2>/dev/null || echo "未知主机")
 
# 确保远程目录存在
$SSH_CMD $REMOTE_USER@$REMOTE_HOST "mkdir -p $REMOTE_DIR" > /dev/null 2>&1

# 检查目录创建是否成功
if [ $? -ne 0 ]; then
  MESSAGE="备份失败:无法在远程服务器 \`$REMOTE_HOSTNAME\` 创建目录 \`$REMOTE_DIR\`!%0A时间:\`$DATE\`"
  echo "备份失败:无法在远程服务器 $REMOTE_HOSTNAME 创建目录 $REMOTE_DIR!"
  curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
    -d chat_id="$CHAT_ID" \
    -d text="$MESSAGE" \
    -d parse_mode="MarkdownV2" > /dev/null 2>&1
  exit 1
fi
 
# 使用 scp 上传备份文件到远程 VPS
if $SCP_CMD "$BACKUP_NAME" $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR > /dev/null 2>&1; then
  # 删除本地备份文件
  rm "$BACKUP_NAME"
 
  # 删除远程备份目录中超过三个的旧备份文件
  $SSH_CMD $REMOTE_USER@$REMOTE_HOST "cd $REMOTE_DIR && ls -t backup_${LOCAL_HOSTNAME}_${LAST_DIR_NAME}_*.tar.gz | tail -n +4 | xargs -r rm -f"
 
  MESSAGE="备份成功!%0A文件:\`$BACKUP_NAME\`%0A上传到服务器:\`$REMOTE_HOSTNAME\`%0A存储路径:\`$REMOTE_DIR\`%0A时间:\`$DATE\`"
  echo "备份成功!文件:$BACKUP_NAME 上传到服务器:$REMOTE_HOSTNAME 存储路径:$REMOTE_DIR 时间:$DATE"
else
  MESSAGE="备份失败:文件上传到 \`$REMOTE_HOST:$REMOTE_DIR\` 失败!%0A请检查:%0A- SSH 密钥是否正确%0A- SSH 端口是否正确(当前端口:\`$REMOTE_PORT\`)%0A时间:\`$DATE\`"
  echo "备份失败:文件上传到 $REMOTE_HOST:$REMOTE_DIR 失败!"
  echo "请检查 SSH 密钥是否正确或 SSH 端口是否正确(当前端口:$REMOTE_PORT)"
fi
 
# 发送 Telegram 通知
if ! curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
  -d chat_id="$CHAT_ID" \
  -d text="$MESSAGE" \
  -d parse_mode="MarkdownV2" > /dev/null 2>&1; then
  echo "Telegram 消息发送失败,请检查 BOT_TOKEN 和 CHAT_ID 是否正确。"
fi