实用脚本能批量SSH吗?

wen 实用脚本 37

本文目录导读:

实用脚本能批量SSH吗?

  1. 基础循环脚本(最常用)
  2. 使用配置文件(推荐)
  3. 并行执行(加速批量操作)
  4. 带错误重试和日志
  5. 期望(Expect)脚本处理密码登录
  6. 高级:使用Ansible(推荐生产环境)
  7. 实用建议

是的,可以批量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 }}"

实用建议

  1. 安全最佳实践

    • 使用SSH密钥,避免明文密码
    • 限制可执行命令范围
    • 配置sudo免密或使用特定用户
  2. 效率提升

    • 使用 ControlMaster 复用SSH连接
    • 设置 -o StrictHostKeyChecking=no 避免交互确认
    • 合理设置超时时间
  3. 错误处理

    # 在~/.ssh/config中配置
    Host *
        ServerAliveInterval 60
        ServerAliveCountMax 3
        ControlMaster auto
        ControlPath ~/.ssh/controlmasters/%r@%h:%p
        ControlPersist 10m

需要哪种特定场景的脚本?我可以帮你定制更适合你的需求的版本。

抱歉,评论功能暂时关闭!