Skip to content
Silubaba trade > Blog > news > 批量多服务器同步执行命令一键脚本

批量多服务器同步执行命令一键脚本

    方案说明

    1. 基于 sshpass 免密登录,适配 50 台服务器批量同步执行
    2. 所有机器同一时间下发命令,并发执行不等待单台返回
    3. 服务器列表单独配置,方便增删 50 台主机
    4. 支持远程执行任意 shell 命令、远程脚本
    5. 输出每台服务器执行结果,区分成功 / 失败

    一、批量执行脚本 batch_exec.sh

    bash

    运行

    #!/bin/bash
    # 50台服务器批量同步执行命令脚本
    # 依赖:sshpass 安装 yum install sshpass -y / apt install sshpass -y
    
    # ===================== 配置区 =====================
    # 服务器列表文件,一行一台 格式:ip 用户名 密码
    HOST_FILE="./hosts.list"
    # 要统一执行的命令,修改这里即可
    RUN_CMD="uptime;df -h;free -h"
    # 并发进程数,50台建议50,一次性全部同时执行
    MAX_PARALLEL=50
    # ==================================================
    
    # 检查依赖
    if ! command -v sshpass &> /dev/null; then
        echo "错误:未安装sshpass,CentOS: yum install sshpass -y  Debian/Ubuntu: apt install sshpass -y"
        exit 1
    fi
    
    # 检查主机列表文件
    if [ ! -f "${HOST_FILE}" ]; then
        echo "错误:主机文件 ${HOST_FILE} 不存在,请创建并填写服务器信息"
        exit 1
    fi
    
    echo "============================================="
    echo "批量同步执行脚本启动,并发数:${MAX_PARALLEL}"
    echo "待执行命令:${RUN_CMD}"
    echo "============================================="
    
    # 循环遍历所有服务器,后台并发执行
    while read -r line
    do
        # 跳过空行和注释行
        [[ -z "$line" || "$line" =~ ^# ]] && continue
    
        # 拆分IP、账号、密码
        IP=$(echo $line | awk '{print $1}')
        USER=$(echo $line | awk '{print $2}')
        PWD=$(echo $line | awk '{print $3}')
    
        # 后台并发执行,不阻塞
        (
            echo -e "\n========== 服务器 $IP 执行结果 =========="
            sshpass -p "${PWD}" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 ${USER}@${IP} "${RUN_CMD}"
            if [ $? -eq 0 ]; then
                echo "【$IP】执行成功"
            else
                echo "【$IP】执行失败,连接/命令异常"
            fi
        ) &
    
        # 控制并发数量
        running=$(jobs -r | wc -l)
        while [ ${running} -ge ${MAX_PARALLEL} ]; do
            sleep 0.1
            running=$(jobs -r | wc -l)
        done
    
    done < ${HOST_FILE}
    
    # 等待所有后台进程全部执行完成
    wait
    echo -e "\n============================================="
    echo "所有服务器命令执行完毕!"
    echo "============================================="
    

    二、服务器列表配置文件 hosts.list

    放在脚本同目录,一行一台,50 台依次往下填

    格式:IP 用户名 密码

    plaintext

    # 示例,删掉#,批量添加50台
    192.168.1.10 root 123456
    192.168.1.11 root 123456
    192.168.1.12 root 123456
    # ... 继续添加到50台
    

    三、免密钥安全替代方案(推荐生产环境)

    1. 本地生成密钥

    bash

    运行

    ssh-keygen -t ed25519
    

    2. 一键推送公钥到所有服务器脚本 push_key.sh

    bash

    运行

    #!/bin/bash
    HOST_FILE="./hosts.list"
    while read line
    do
        [[ -z "$line" || "$line" =~ ^# ]] && continue
        IP=$(echo $line | awk '{print $1}')
        USER=$(echo $line | awk '{print $2}')
        PWD=$(echo $line | awk '{print $3}')
        sshpass -p $PWD ssh-copy-id -o StrictHostKeyChecking=no $USER@$IP
    done < $HOST_FILE
    

    推送完成后,原执行脚本可以删掉 sshpass,不再明文存密码,更安全:

    修改执行脚本里 ssh 这一行:

    bash

    运行

    ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 ${USER}@${IP} "${RUN_CMD}"
    

    四、使用步骤

    1. 安装依赖

    bash

    运行

    # CentOS/RHEL
    yum install sshpass -y
    # Ubuntu/Debian
    apt update && apt install sshpass -y
    
    1. 创建 hosts.list 填入 50 台服务器信息
    2. 赋予执行权限

    bash

    运行

    chmod +x batch_exec.sh
    
    1. 修改脚本内 RUN_CMD 为你需要统一执行的命令
    2. 一键批量同步执行所有机器

    bash

    运行

    ./batch_exec.sh
    

    五、常用扩展用法

    1. 远程执行本地脚本文件 修改 RUN_CMD 改为传输 + 执行:

    bash

    运行

    RUN_CMD="cat > /tmp/tmp_script.sh && chmod +x /tmp/tmp_script.sh && /tmp/tmp_script.sh"
    # 调用方式:cat local_script.sh | ./batch_exec.sh
    
    1. 批量重启服务

    bash

    运行

    RUN_CMD="systemctl restart nginx"
    
    1. 批量上传文件到所有服务器

    bash

    运行

    RUN_CMD="cat > /tmp/test.tar.gz"
    # 使用:cat test.tar.gz | ./batch_exec.sh
    

    六、关键特性

    • 50 台服务器同时并发执行,同一时间下发指令,无串行等待
    • 超时 5 秒,防止某台服务器卡死阻塞全部任务
    • 自动跳过注释、空行,方便管理大量主机
    • 每台机器独立输出执行日志,方便定位失败机器
    • 支持修改并发数,低配机器可调低并发避免本地负载过高

    Leave a Reply