本文目录导读:

是的,可以批量SSH,以下是几种实用的批量SSH脚本方案,从简单到复杂:
基础循环脚本(最常用)
#!/bin/bash
# batch_ssh.sh - 批量执行命令
# 服务器列表
SERVERS=(
"192.168.1.10"
"192.168.1.11"
"192.168.1.12"
)
# SSH配置
USER="root"
KEY="/path/to/private_key"
COMMAND="uptime && free -h" # 要执行的命令
for SERVER in "${SERVERS[@]}"; do
echo "=== 正在连接: $SERVER ==="
ssh -i "$KEY" -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$USER@$SERVER" "$COMMAND"
if [ $? -eq 0 ]; then
echo "✓ $SERVER 执行成功"
else
echo "✗ $SERVER 执行失败"
fi
echo "------------------------"
done
使用配置文件(推荐)
#!/bin/bash
# batch_ssh_config.sh
CONFIG_FILE="servers.txt"
COMMAND="df -h | grep -E '(/dev|/mnt)'"
# servers.txt 格式:
# 服务器IP 端口 用户名 私钥路径
# 192.168.1.10 22 root /path/key1
# 192.168.1.11 22 admin /path/key2
while IFS=' ' read -r IP PORT USER KEY; do
echo "检查: $USER@$IP:$PORT"
ssh -i "$KEY" -p "$PORT" -o ConnectTimeout=5 "$USER@$IP" "$COMMAND"
if [ $? -eq 0 ]; then
echo "✓ $IP 成功"
else
echo "✗ $IP 失败"
fi
done < "$CONFIG_FILE"
并行执行(加速批量操作)
#!/bin/bash
# batch_ssh_parallel.sh - 使用parallel或后台进程
SERVERS=("server1" "server2" "server3")
USER="root"
CMD="hostname && date"
# 方法1:使用后台进程
for SVR in "${SERVERS[@]}"; do
(
ssh "$USER@$SVR" "$CMD"
) &
done
wait # 等待所有后台进程完成
# 方法2:使用GNU parallel(需要安装)
# parallel -j 5 ssh {} "hostname" ::: "${SERVERS[@]}"
# 方法3:使用xargs
# printf "%s\n" "${SERVERS[@]}" | xargs -I {} -P 5 ssh "$USER@{}" "$CMD"
带错误重试和日志
#!/bin/bash
# batch_ssh_robust.sh
SERVERS=("10.0.0.1" "10.0.0.2" "10.0.0.3")
USER="admin"
LOG_FILE="ssh_batch_$(date +%Y%m%d_%H%M%S).log"
RETRY=2
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
execute_ssh() {
local server=$1
local cmd=$2
local retry=$3
for ((i=1; i<=retry; i++)); do
log "尝试 $i/$retry: $server"
if ssh -o ConnectTimeout=10 "$USER@$server" "$cmd" 2>/dev/null; then
log "✓ $server 成功"
return 0
fi
log "✗ $server 失败,等待重试..."
sleep 2
done
log "✗ $server 最终失败"
return 1
}
# 主执行
for SERVER in "${SERVERS[@]}"; do
execute_ssh "$SERVER" "uptime" $RETRY
done
期望(Expect)脚本处理密码登录
#!/usr/bin/expect -f
# batch_ssh_expect.exp
set timeout 10
set username "root"
set password "your_password"
# 读取服务器列表文件
set f [open "servers.txt" r]
while {[gets $f line] >= 0} {
set server [string trim $line]
spawn ssh $username@$server "hostname && date"
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$password\r" }
timeout { puts "超时: $server"; continue }
eof { puts "完成: $server" }
}
}
close $f
高级:使用Ansible(推荐生产环境)
# ansible_batch.yml
---
- name: 批量执行命令
hosts: all
gather_facts: no
tasks:
- name: 检查系统信息
shell: |
echo "=== {{ inventory_hostname }} ==="
uptime
df -h /
free -m
register: result
- debug:
msg: "{{ result.stdout_lines }}"
实用建议
-
安全最佳实践:
- 使用SSH密钥,避免明文密码
- 限制可执行命令范围
- 配置sudo免密或使用特定用户
-
效率提升:
- 使用
ControlMaster复用SSH连接 - 设置
-o StrictHostKeyChecking=no避免交互确认 - 合理设置超时时间
- 使用
-
错误处理:
# 在~/.ssh/config中配置 Host * ServerAliveInterval 60 ServerAliveCountMax 3 ControlMaster auto ControlPath ~/.ssh/controlmasters/%r@%h:%p ControlPersist 10m
需要哪种特定场景的脚本?我可以帮你定制更适合你的需求的版本。