linux服务器批量复制文件
copy_multiple_folders.sh
#!/bin/bash
# =====================================================
# copy_folders_to_multi_servers.sh
# 功能:将多个本地文件夹复制到多台远程服务器的不同路径
# 每个 (本地文件夹 → 远程用户@主机:路径) 独立配置
# 依赖:scp, ssh, ping
# 使用前请确保已配置 SSH 免密登录
# =====================================================
# ---------- 配置区 ----------
# 日志文件
LOG_FILE="./deploy_$(date +%Y%m%d_%H%M%S).log"
# 定义传输任务列表
# 格式:("本地路径" "user@host" "远程路径" "端口")
# 可添加任意多条,每条任务独立
TASKS=(
"/opt/app/web" "root@192.168.1.10" "/var/www/html/" "22"
"/opt/app/api" "ubuntu@192.168.1.11" "/home/ubuntu/api/" "22"
"/opt/config/nginx" "admin@192.168.1.12" "/etc/nginx/conf.d/" "2222"
"/opt/scripts" "root@192.168.1.13" "/root/bin/" "22"
# 示例:
# 本地文件夹 用户@主机 远程路径 SSH端口
)
# -----------------------------
# 私钥路径(可选,如使用密码登录可留空)
PRIVATE_KEY="$HOME/.ssh/id_rsa"
# 超时设置
PING_TIMEOUT=3
SCP_TIMEOUT=30
# 初始化日志
echo "🚀 开始批量部署任务: $(date)" > "$LOG_FILE"
echo "📌 总共 $((${#TASKS[@]} / 4)) 个传输任务" >> "$LOG_FILE"
echo "----------------------------------------" >> "$LOG_FILE"
ERROR_COUNT=0
SUCCESS_COUNT=0
# 检查工具依赖
for cmd in scp ssh ping; do
if ! command -v $cmd &> /dev/null; then
echo "❌ 错误:系统未安装 $cmd,请先安装。"
exit 1
fi
done
# 循环处理每个任务
for ((i = 0; i < ${#TASKS[@]}; i += 4)); do
LOCAL_PATH="${TASKS[i]}"
REMOTE_USER_HOST="${TASKS[i+1]}"
REMOTE_PATH="${TASKS[i+2]}"
PORT="${TASKS[i+3]}"
# 提取主机用于 ping 检测
HOST=$(echo "$REMOTE_USER_HOST" | cut -d'@' -f2)
echo "🔁 处理任务: $LOCAL_PATH → $REMOTE_USER_HOST:$REMOTE_PATH"
# 1. 检查本地路径是否存在
if [ ! -d "$LOCAL_PATH" ]; then
echo "❌ 失败: 本地文件夹不存在 → $LOCAL_PATH"
echo "[$(date +%T)] ERROR: 本地路径不存在: $LOCAL_PATH" >> "$LOG_FILE"
((ERROR_COUNT++))
continue
fi
# 2. 检查网络连通性
if ! ping -c 1 -W $PING_TIMEOUT "$HOST" &> /dev/null; then
echo "❌ 失败: 无法连接到主机 → $HOST"
echo "[$(date +%T)] ERROR: 主机不可达: $HOST" >> "$LOG_FILE"
((ERROR_COUNT++))
continue
fi
# 3. 构建 scp 命令
SCP_CMD="scp -r -P $PORT -o ConnectTimeout=$SCP_TIMEOUT"
# 添加私钥(如果存在)
if [ -n "$PRIVATE_KEY" ] && [ -f "$PRIVATE_KEY" ]; then
SCP_CMD="$SCP_CMD -i $PRIVATE_KEY"
fi
# 添加目标
SCP_CMD="$SCP_CMD \"$LOCAL_PATH\" $REMOTE_USER_HOST:\"$REMOTE_PATH\""
# 执行命令
echo "📡 正在上传: $LOCAL_PATH → $REMOTE_USER_HOST:$REMOTE_PATH"
eval $SCP_CMD >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "✅ 成功: $LOCAL_PATH → $REMOTE_USER_HOST:$REMOTE_PATH"
echo "[$(date +%T)] SUCCESS: $LOCAL_PATH → $REMOTE_USER_HOST:$REMOTE_PATH" >> "$LOG_FILE"
((SUCCESS_COUNT++))
else
echo "❌ 失败: $LOCAL_PATH → $REMOTE_USER_HOST:$REMOTE_PATH"
echo "[$(date +%T)] FAILED: $LOCAL_PATH → $REMOTE_USER_HOST:$REMOTE_PATH" >> "$LOG_FILE"
((ERROR_COUNT++))
fi
echo "" >> "$LOG_FILE"
done
# 输出最终结果
echo ""
echo "========================================"
echo "📊 任务完成!成功: $SUCCESS_COUNT,失败: $ERROR_COUNT"
echo "📄 详细日志: $LOG_FILE"
echo "========================================"
if [ $ERROR_COUNT -eq 0 ]; then
echo "🎉 所有任务执行成功!"
exit 0
else
echo "❌ 存在 $ERROR_COUNT 个任务失败,请检查日志。"
exit 1
fi