前置说明
支持 redhat/centos。fedora ,ubuntu,debian ,suse linux
- 所有服务器配置SSH 免密登录(本机生成密钥分发到所有节点,否则每次输密码)
- 服务器列表单独维护,方便增删节点
- 两种模式:
- 模式 1:批量并行执行命令(速度快)
- 模式 2:串行依次执行(方便看单台输出,排错用)
1、批量执行脚本 batch_ssh.sh
bash
运行
#!/bin/bash
# 多服务器批量执行命令脚本
# 作者:Batch SSH Tool
# 日期:2026-06-19
# ===================== 配置区 自行修改 =====================
# 服务器清单文件,一行一个 格式:用户名@IP 如 root@192.168.1.10
SERVER_LIST="./server_list.txt"
# SSH端口,非22端口自行修改
SSH_PORT=22
# 并行并发数量,50台建议设20,防止ssh并发过高卡死
MAX_PARALLEL=20
# ==========================================================
# 检查服务器列表文件是否存在
if [ ! -f "${SERVER_LIST}" ]; then
echo "错误:服务器清单文件 ${SERVER_LIST} 不存在!"
echo "请创建文件,每行填写一台服务器:root@10.0.0.1"
exit 1
fi
# 判断是否传入执行命令
if [ $# -eq 0 ]; then
echo "使用方法:"
echo " 1. 串行执行:bash batch_ssh.sh '你要执行的命令'"
echo " 2. 并行快速执行:bash batch_ssh.sh -p '你要执行的命令'"
echo ""
echo "示例:"
echo "bash batch_ssh.sh 'df -h'"
echo "bash batch_ssh.sh -p 'systemctl restart nginx'"
exit 1
fi
# 并行模式标识
RUN_PARALLEL=0
if [ "$1" = "-p" ]; then
RUN_PARALLEL=1
EXEC_CMD="$2"
else
EXEC_CMD="$1"
fi
echo "============================================="
echo "待执行命令:${EXEC_CMD}"
echo "并发模式:$([ ${RUN_PARALLEL} -eq 1 ] && echo 并行 || echo 串行)"
echo "服务器列表文件:${SERVER_LIST}"
echo "============================================="
echo ""
# 串行执行函数
run_serial() {
while read -r host; do
# 跳过空行、注释行
[[ -z "$host" || "$host" =~ ^# ]] && continue
echo -e "\033[32m========== 正在执行 ${host} ==========\033[0m"
ssh -p ${SSH_PORT} -o ConnectTimeout=5 -o StrictHostKeyChecking=no "${host}" "${EXEC_CMD}"
echo -e "\033[33m========== ${host} 执行完成 ==========\033[0m"
echo ""
done < "${SERVER_LIST}"
}
# 并行执行函数
run_parallel() {
# 用xargs控制并发
grep -v '^#' "${SERVER_LIST}" | grep -v '^$' | xargs -P ${MAX_PARALLEL} -I {} bash -c "
echo -e '\033[32m========== 正在执行 {} ==========\033[0m'
ssh -p ${SSH_PORT} -o ConnectTimeout=5 -o StrictHostKeyChecking=no {} '${EXEC_CMD}'
echo -e '\033[33m========== {} 执行完成 ==========\033[0m'
echo ''
"
}
# 选择执行模式
if [ ${RUN_PARALLEL} -eq 1 ]; then
run_parallel
else
run_serial
fi
echo "所有服务器命令执行完毕!"
2、服务器清单文件 server_list.txt
和脚本放同一目录,填写 50 台服务器,支持 #注释
txt
# 示例格式 用户名@IP
root@192.168.1.1
root@192.168.1.2
root@192.168.1.3
# root@192.168.1.4 注释掉代表不执行
root@192.168.1.5
# 往下补齐50台服务器
3、免密 SSH 一键分发脚本(配套工具 ssh_copy_key.sh)
批量推送本机公钥到 50 台服务器,不用每次输密码
bash
运行
#!/bin/bash
SERVER_LIST="./server_list.txt"
SSH_PORT=22
# 不存在密钥则生成
if [ ! -f ~/.ssh/id_rsa ]; then
echo "未检测到ssh密钥,自动生成..."
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
fi
while read -r host; do
[[ -z "$host" || "$host" =~ ^# ]] && continue
echo "分发密钥至 ${host}"
ssh-copy-id -p ${SSH_PORT} -o StrictHostKeyChecking=no "${host}"
done < "${SERVER_LIST}"
echo "全部服务器免密配置完成"
4、使用步骤
步骤 1:赋执行权限
bash
运行
chmod +x batch_ssh.sh ssh_copy_key.sh
步骤 2:配置免密登录(必须做)
bash
运行
bash ssh_copy_key.sh
步骤 3:修改 server_list.txt 填入全部 50 台服务器 IP
步骤 4:执行命令
串行执行(一台跑完再下一台,输出清晰)
bash
运行
# 查看磁盘
bash batch_ssh.sh "df -h"
# 重启服务
bash batch_ssh.sh "systemctl restart docker"
# 查看内存
bash batch_ssh.sh "free -h"
并行快速执行(50 台同时跑,速度快)
bash
运行
bash batch_ssh.sh -p "uptime"
bash batch_ssh.sh -p "yum update -y"
脚本内置优化点
ConnectTimeout=5:服务器失联 5 秒自动跳过,不卡死StrictHostKeyChecking=no:首次连接不弹确认框- 过滤空行、# 注释,方便临时屏蔽某台机器
- 并发控制,避免一次性 50 个 SSH 连接打满本机资源
- 彩色输出区分每台服务器执行日志
- 兼容自定义 SSH 端口(修改脚本顶部
SSH_PORT即可)
补充:无免密场景(需要输密码)
如果不能配置免密,安装sshpass工具,修改脚本 ssh 行:
bash
运行
sshpass -p "服务器密码" ssh -p ${SSH_PORT} ...