SSH 操作晋级:批量管理多台服务器的 3 种高效方案,附脚本示例
SSH 操作晋级:批量管理多台服务器的 3 种高效方案,附脚本示例
引言:多服务器管理的 “手动噩梦”
当你需要管理 10 台以上服务器时,是否每天都在重复这些操作:
逐台登录服务器执行uptime查看负载,复制粘贴 10 次命令;
每台服务器都要传同一个配置文件,scp命令执行 10 遍;
批量重启服务时,盯着终端等待每台执行完成,耗时半小时 —— 这些 “重复劳动” 不仅浪费时间,还容易因手动操作失误导致配置不一致。
SSH 批量管理的核心是 “用工具 / 脚本替代手动输入”,实现 “一次操作,多台生效”。本文分享的 3 种方案,覆盖从 “简单场景(10 台内)” 到 “复杂场景(100 台 +)” 的全需求,每种方案都附可直接运行的脚本,帮你快速摆脱 “手动管理” 的泥潭,向 “自动化运维” 进阶。
前置准备:批量管理的 “基础前提”
在开始批量操作前,必须先完成密钥免密登录配置—— 否则每台服务器都要输入密码,批量操作会失效。若你还未配置,可通过以下脚本批量分发密钥(以 10 台服务器为例):
1. 密钥批量分发脚本(expect 实现)
| #!/usr/bin/expect # 用法:./batch-ssh-copy-id.sh 服务器列表文件 服务器密码 本地公钥路径 set servers [open [lindex $argv 0] r] set password [lindex $argv 1] set pub_key [lindex $argv 2] # 循环分发密钥到每台服务器 while {[gets $servers line] != -1} { # 解析服务器信息(格式:用户名@IP:端口,如www@10.0.0.10:2222) regexp {([^@]+)@([^:]+):?(d*)} $line -> user ip port if {$port eq ""} {set port 22} # 默认端口22 puts " === 正在向 $user@$ip:$port 分发密钥 ===" spawn ssh-copy-id -i $pub_key -p $port $user@$ip expect { "Are you sure you want to continue connecting" { send "yes " exp_continue } "password:" { send "$password " } } expect eof } close $servers puts " === 所有服务器密钥分发完成 ===" |
2. 使用步骤
- 准备服务器列表文件(servers.txt),每行一条记录:
| www@10.0.0.10:2222 www@10.0.0.11:2222 www@10.0.0.12:2222 # 共10台,此处省略其他7台... |
- 安装 expect 工具(CentOS/Ubuntu):
| # CentOS/RHEL sudo yum install expect -y # Ubuntu/Debian sudo apt install expect -y |
- 执行脚本分发密钥(替换为你的密码和公钥路径):
| chmod +x batch-ssh-copy-id.sh ./batch-ssh-copy-id.sh servers.txt "你的服务器密码" ~/.ssh/id_ed25519.pub |
完成后,所有服务器均可免密登录,接下来的批量方案才能正常生效。
方案 1:Shell 循环(零工具依赖,适合 10 台内简单场景)
适用场景
- 服务器数量少(10 台以内),无需并行执行;
- 仅需执行简单命令(如查看负载、复制文件);
- 不想安装额外工具,依赖系统自带的 Shell 能力。
核心原理
通过for循环遍历服务器列表,逐台执行 SSH 命令或 SCP 操作,实现批量管控。
实战示例:3 个常用脚本
示例 1:批量执行命令(查看所有服务器负载)
| #!/bin/bash # 批量执行命令脚本:./batch-cmd.sh "要执行的命令" cmd=$1 # 服务器列表(可替换为从文件读取:servers=($(cat servers.txt))) servers=("www@10.0.0.10:2222" "www@10.0.0.11:2222" "www@10.0.0.12:2222") # 循环执行命令 for server in "${servers[@]}"; do # 解析用户名、IP、端口 user=$(echo $server | cut -d'@' -f1) ip_port=$(echo $server | cut -d'@' -f2) ip=$(echo $ip_port | cut -d':' -f1) port=$(echo $ip_port | cut -d':' -f2)
echo -e " === 服务器 $ip:$port 执行结果 ===" # 执行命令(若需sudo,添加 -t 参数:ssh -p |





