本文目录导读:

- SSH + Shell 脚本 (Linux/Unix)
- 使用 parallel-ssh (pssh)
- Python 脚本 (使用 paramiko)
- Ansible (推荐)
- 使用 expect 脚本
- 使用 Fabric (Python)
- 高级 Shell 脚本示例
- Docker 容器批量管理
- 使用 tmux 批量管理
- 快捷实用脚本
- 使用建议
SSH + Shell 脚本 (Linux/Unix)
使用密码认证 (需要 sshpass)
#!/bin/bash
# bulk_ssh.sh
SERVER_LIST="server1 server2 server3"
USERNAME="your_user"
PASSWORD="your_password"
COMMAND="df -h"
for server in $SERVER_LIST; do
echo "=== Executing on $server ==="
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no "$USERNAME@$server" "$COMMAND"
done
使用密钥认证
#!/bin/bash
HOSTS=(
"192.168.1.10"
"192.168.1.11"
"192.168.1.12"
)
USER="root"
COMMAND="uptime && free -h"
for host in "${HOSTS[@]}"; do
echo "Connecting to $host..."
ssh -i ~/.ssh/id_rsa -o ConnectTimeout=5 "$USER@$host" "$COMMAND"
done
使用 parallel-ssh (pssh)
#!/bin/bash # 安装: apt-get install pssh 或 pip install pssh # 创建主机列表文件 cat > hosts.txt << EOF user1@192.168.1.10 user2@192.168.1.11 user3@192.168.1.12 EOF # 并行执行命令 pssh -h hosts.txt -l root -A -i "uptime && docker ps" # 参数说明: # -h: 主机列表文件 # -l: 用户名 # -A: 询问密码 # -i: 显示输出 # -p: 并行数 (默认32)
Python 脚本 (使用 paramiko)
#!/usr/bin/env python3
# bulk_exec.py
import paramiko
import threading
from concurrent.futures import ThreadPoolExecutor
def execute_remote(host, username, password, command):
"""在远程主机执行命令"""
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=username, password=password, timeout=10)
stdin, stdout, stderr = ssh.exec_command(command)
output = stdout.read().decode('utf-8')
error = stderr.read().decode('utf-8')
print(f"\n=== {host} ===")
if output:
print(f"Output:\n{output}")
if error:
print(f"Error:\n{error}")
ssh.close()
return True
except Exception as e:
print(f"Failed to connect to {host}: {str(e)}")
return False
def main():
# 服务器配置
servers = [
{"host": "192.168.1.10", "user": "root", "pass": "pass1"},
{"host": "192.168.1.11", "user": "root", "pass": "pass2"},
{"host": "192.168.1.12", "user": "admin", "pass": "pass3"},
]
command = input("请输入要执行的命令: ")
# 并行执行
with ThreadPoolExecutor(max_workers=10) as executor:
futures = []
for server in servers:
future = executor.submit(
execute_remote,
server["host"],
server["user"],
server["pass"],
command
)
futures.append(future)
# 等待所有完成
for future in futures:
future.result()
if __name__ == "__main__":
main()
Ansible (推荐)
---
- name: 批量执行命令
hosts: all
gather_facts: no
vars:
ansible_ssh_private_key_file: /path/to/private/key
tasks:
- name: 执行系统命令
shell: |
uptime
free -h
df -h
register: result
- name: 显示结果
debug:
msg: "{{ result.stdout_lines }}"
使用 ansible-adhoc (一行命令)
# 单条命令 ansible all -i inventory.ini -m shell -a "df -h" -u root -k # 多条命令 ansible all -i inventory.ini -m shell -a "uptime; free -h; who" -u root -k
使用 expect 脚本
#!/usr/bin/expect -f
# batch_exec.exp
set timeout 10
set servers {server1 server2 server3}
set username "admin"
set password "password123"
set command "hostname && date"
foreach server $servers {
spawn ssh $username@$server
expect {
"password:" {
send "$password\r"
}
"yes/no" {
send "yes\r"
exp_continue
}
}
expect "$ "
send "$command\r"
expect "$ "
puts "\n--- Completed on $server ---"
send "exit\r"
}
使用 Fabric (Python)
#!/usr/bin/env python3
# bulk_fabric.py
from fabric import Connection, Config
from concurrent.futures import ThreadPoolExecutor
def execute_command(host, user, command):
"""在单个主机执行命令"""
try:
config = Config(overrides={
'connect_kwargs': {'password': 'your_password'}
})
with Connection(
host=host,
user=user,
config=config,
connect_kwargs={'timeout': 10}
) as conn:
result = conn.run(command, hide=True)
print(f"\n=== {host} ===")
print(result.stdout)
except Exception as e:
print(f"Error on {host}: {e}")
def main():
hosts = [
"192.168.1.10",
"192.168.1.11",
"192.168.1.12"
]
command = "uptime && free -h"
with ThreadPoolExecutor(max_workers=5) as executor:
for host in hosts:
executor.submit(execute_command, host, "root", command)
if __name__ == "__main__":
main()
高级 Shell 脚本示例
#!/bin/bash
# 批量部署检查脚本
# 配置
SERVER_FILE="servers.txt"
LOG_DIR="./logs"
SSH_USER="root"
SSH_KEY="~/.ssh/id_rsa"
TIMEOUT=5
# 创建日志目录
mkdir -p "$LOG_DIR"
# 检查主机列表
if [ ! -f "$SERVER_FILE" ]; then
echo "错误: 找不到服务器列表文件 $SERVER_FILE"
echo "格式: IP 或 hostname, 每行一个"
exit 1
fi
# 定义要执行的命令数组
COMMANDS=(
"echo '=== 系统信息 ==='; uname -a"
"echo '=== 内存使用 ==='; free -h"
"echo '=== 磁盘使用 ==='; df -h"
"echo '=== 运行时间 ==='; uptime"
"echo '=== Docker 容器 ==='; docker ps --format 'table {{.Names}}\t{{.Status}}' 2>/dev/null || echo 'Docker not installed'"
)
# 进度显示
show_progress() {
local current=$1
local total=$2
local percent=$((current * 100 / total))
printf "\rProgress: [%-50s] %d%%" $(printf '#%.0s' $(seq 1 $((percent / 2)))) $percent
}
# 主执行函数
execute_remote() {
local server=$1
local log_file="$LOG_DIR/${server//./_}_$(date +%Y%m%d_%H%M%S).log"
{
echo "========================================"
echo "执行时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "服务器: $server"
echo "========================================"
for cmd in "${COMMANDS[@]}"; do
echo -e "\n--- 执行命令: $cmd ---"
ssh -i "$SSH_KEY" -o ConnectTimeout=$TIMEOUT \
-o StrictHostKeyChecking=no \
"$SSH_USER@$server" "$cmd" 2>&1
done
} > "$log_file"
# 检查是否成功
if [ $? -eq 0 ]; then
echo "$server: 成功" >> "$LOG_DIR/summary.log"
else
echo "$server: 失败" >> "$LOG_DIR/summary.log"
fi
}
# 读取服务器列表并执行
echo "开始批量执行..."
total_servers=$(wc -l < "$SERVER_FILE")
counter=0
while IFS= read -r server; do
[ -z "$server" ] && continue # 跳过空行
server=$(echo "$server" | tr -d '[:space:]')
((counter++))
show_progress $counter $total_servers
execute_remote "$server" &
# 控制并发数
while [ $(jobs -r | wc -l) -ge 10 ]; do
sleep 1
done
done < "$SERVER_FILE"
# 等待所有后台任务完成
wait
echo -e "\n\n执行完成!"
echo "详细日志保存在: $LOG_DIR/"
cat "$LOG_DIR/summary.log"
# 生成汇总报告
echo ""
echo "========================================"
echo "执行汇总"
echo "========================================"
echo "成功: $(grep -c "成功" $LOG_DIR/summary.log) 台"
echo "失败: $(grep -c "失败" $LOG_DIR/summary.log) 台"
echo "总共: $total_servers 台"
Docker 容器批量管理
#!/bin/bash
# Docker 批量管理脚本
# 定义Docker主机
declare -A DOCKER_HOSTS
DOCKER_HOSTS=(
["server1"]="192.168.1.10"
["server2"]="192.168.1.11"
["server3"]="192.168.1.12"
)
# 要执行的Docker命令
DOCKER_COMMANDS=(
"docker ps --format 'table {{.Names}}\t{{.Status}}'"
"docker stats --no-stream"
"docker system df"
)
for host_name in "${!DOCKER_HOSTS[@]}"; do
host_ip=${DOCKER_HOSTS[$host_name]}
echo "=========================================="
echo "处理服务器: $host_name ($host_ip)"
echo "=========================================="
# 设置Docker远程API
export DOCKER_HOST="tcp://$host_ip:2375"
for cmd in "${DOCKER_COMMANDS[@]}"; do
echo "--- 执行: $cmd ---"
eval "$cmd" 2>&1 || echo "执行失败"
echo ""
done
done
使用 tmux 批量管理
#!/bin/bash
# tmux_bulk.sh - 使用tmux同步操作
SESSION="admin_session"
SERVERS=("server1" "server2" "server3")
# 创建tmux会话
tmux new-session -d -s "$SESSION"
# 创建窗口
for i in "${!SERVERS[@]}"; do
if [ $i -eq 0 ]; then
window="0"
else
tmux new-window -t "$SESSION:$i"
window="$i"
fi
# SSH到远程服务器
tmux send-keys -t "$SESSION:$window" "ssh ${SERVERS[$i]}" Enter
done
# 开启同步(主控模式)
tmux set-window-option -t "$SESSION:0" synchronize-panes on
# 附加到会话
tmux attach-session -t "$SESSION"
echo "提示: 在任意窗口输入命令,所有窗口会同步执行"
echo "按 Ctrl+B + Alt + 方向键 切换窗口"
echo "输入 exit 退出连接"
快捷实用脚本
#!/bin/bash
# 常用命令快捷批量执行
# 1. 批量更新系统
update_system() {
for host in $(cat servers.txt); do
ssh "$host" "apt update && apt upgrade -y"
done
}
# 2. 批量检查服务
check_services() {
local services=("nginx" "mysql" "docker" "ssh")
for host in $(cat servers.txt); do
echo "=== $host ==="
for service in "${services[@]}"; do
status=$(ssh "$host" "systemctl is-active $service" 2>/dev/null)
echo "$service: $status"
done
done
}
# 3. 批量重启服务
restart_services() {
local services=$@
for host in $(cat servers.txt); do
echo "Restarting on $host..."
for service in $services; do
ssh "$host" "systemctl restart $service"
done
done
}
# 主菜单
case "$1" in
update)
update_system
;;
check)
check_services
;;
restart)
shift
restart_services $@
;;
*)
echo "用法: $0 {update|check|restart [service]}"
exit 1
;;
esac
使用建议
-
安全性:
- 优先使用 SSH 密钥认证
- 不要在脚本中硬编码密码
- 考虑使用 SSH Agent
-
性能优化:
- 使用并行执行提高效率
- 控制并发数避免负载过高
- 设置超时防止脚本挂起
-
错误处理:
- 添加连接失败重试机制
- 记录详细日志
- 提供执行结果汇总
-
选择建议:
- 小型环境:Shell脚本 + sshpass
- 中型环境:Python + paramiko
- 大型环境:Ansible/Fabric
- Docker环境:Docker API + 脚本
选择哪种方式取决于你的具体需求、环境规模和安全要求。