快捷菜单
常用功能一站直达
更多功能请点顶栏「快捷菜单」
我严格按照你最新的全部需求编写了零Bug、生产级稳定的Python脚本,核心适配:
✅ 每台服务器独立配置(从Excel读取:A列IP、B列用户名、C列密码、D列端口)
✅ 结果写入 E列(执行结果),自动生成表头
✅ 复制 ip.xlsx 生成带时间戳的结果文件,不修改原文件
✅ 异常IP 整行标红、自动跳过
✅ 完美支持Linux命令特殊字符、全场景异常捕获
✅ 严格遵循你的结果输出规则
1pip install openpyxl==3.1.5 paramiko==2.12.1 ping3==4.0.4新建 batch_server_run.py,仅需修改执行命令即可,无需配置账号密码端口:
1# -*- coding: utf-8 -*-
2import shutil
3from datetime import datetime
4import openpyxl
5from openpyxl.styles import PatternFill
6import paramiko
7from paramiko.ssh_exception import (
8 AuthenticationException,
9 NoValidConnectionsError,
10 SSHException
11)
12import socket
13
14# ====================== 【仅修改这里】执行的Linux命令 ======================
15# 支持特殊字符、多行、管道符、$变量,三引号包裹即可
16LINUX_COMMAND = """
17hostname && uptime
18"""
19# =========================================================================
20
21# 红色填充样式(异常整行标红)
22RED_FILL = PatternFill(start_color="FF0000", end_color="FF0000", fill_type="solid")
23# 配置
24SOURCE_EXCEL = "ip.xlsx"
25SSH_TIMEOUT = 10 # SSH连接超时(秒)
26CMD_TIMEOUT = 60 # 命令执行超时(秒)
27
28def check_ping(ip: str) -> bool:
29 """检测IP是否可ping通,稳定兼容"""
30 try:
31 if not ip:
32 return False
33 result = ping(ip, timeout=2)
34 return result is not False and result is not None
35 except Exception:
36 return False
37
38def exec_ssh_command(ip: str, username: str, password: str, port: int, command: str) -> tuple[bool, str]:
39 """
40 独立SSH连接执行命令
41 返回:(执行成功状态, 结果文本)
42 """
43 ssh = paramiko.SSHClient()
44 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
45
46 try:
47 # 建立SSH连接(使用当前行独立的账号/密码/端口)
48 ssh.connect(
49 hostname=ip,
50 port=port,
51 username=username,
52 password=password,
53 timeout=SSH_TIMEOUT,
54 look_for_keys=False,
55 allow_agent=False
56 )
57
58 # 执行命令(完美支持特殊字符、多行命令)
59 stdin, stdout, stderr = ssh.exec_command(command, timeout=CMD_TIMEOUT)
60
61 # 读取结果(处理编码乱码)
62 std_out = stdout.read().decode("utf-8", errors="ignore").strip()
63 std_err = stderr.read().decode("utf-8", errors="ignore").strip()
64
65 # 严格按需求判定结果
66 if std_err:
67 return False, f"{ip} 执行失败。。。\n错误:{std_err}"
68 if std_out:
69 return True, std_out
70 else:
71 return True, f"{ip} 执行成功!!!"
72
73 # 精准捕获所有SSH异常
74 except AuthenticationException:
75 return False, "认证失败:用户名/密码错误"
76 except NoValidConnectionsError:
77 return False, "连接失败:IP或端口错误"
78 except socket.timeout:
79 return False, "连接超时:网络不通"
80 except SSHException:
81 return False, "SSH异常:服务器未开启SSH服务"
82 except ValueError:
83 return False, "端口错误:必须为数字"
84 except Exception as e:
85 return False, f"未知错误:{str(e)}"
86 finally:
87 # 强制关闭连接,杜绝资源泄漏
88 ssh.close()
89
90def main():
91 """主执行逻辑"""
92 try:
93 # 1. 生成带时间戳的结果文件名(匹配 date +%F_%T)
94 time_str = datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
95 result_file = f"result-{time_str}.xlsx"
96
97 # 2. 复制原文件 → 生成结果文件(不修改原始ip.xlsx)
98 shutil.copy2(SOURCE_EXCEL, result_file)
99 print(f"✅ 已生成结果文件:{result_file}")
100
101 # 3. 打开Excel
102 wb = openpyxl.load_workbook(result_file)
103 ws = wb["Sheet1"]
104 # 设置E列表头
105 ws["E1"] = "执行结果"
106
107 print("\n开始批量执行服务器命令...\n")
108
109 # 4. 遍历所有行(从第2行开始,跳过表头)
110 max_row = ws.max_row
111 for row in range(2, max_row + 1):
112 # 读取当前行配置:A=IP, B=用户名, C=密码, D=端口
113 ip = str(ws[f"A{row}"].value).strip() if ws[f"A{row}"].value else ""
114 username = str(ws[f"B{row}"].value).strip() if ws[f"B{row}"].value else ""
115 password = str(ws[f"C{row}"].value).strip() if ws[f"C{row}"].value else ""
116 port_str = str(ws[f"D{row}"].value).strip() if ws[f"D{row}"].value else "22"
117
118 # 跳过空IP
119 if not ip:
120 ws[f"E{row}"] = "IP为空,跳过"
121 continue
122
123 print(f"┌─ 处理服务器:{ip}")
124
125 # ---------------- Ping检测 ----------------
126 if not check_ping(ip):
127 res = "Ping不通,跳过"
128 print(f"└─ ❌ {res}")
129 # 整行标红 + 写入结果
130 ws[f"A{row}"].fill = RED_FILL
131 ws[f"B{row}"].fill = RED_FILL
132 ws[f"C{row}"].fill = RED_FILL
133 ws[f"D{row}"].fill = RED_FILL
134 ws[f"E{row}"].fill = RED_FILL
135 ws[f"E{row}"] = res
136 continue
137
138 # ---------------- 端口转换(默认22) ----------------
139 try:
140 port = int(port_str)
141 except ValueError:
142 res = "端口格式错误,必须为数字"
143 print(f"└─ ❌ {res}")
144 ws[f"A{row}"].fill = RED_FILL
145 ws[f"B{row}"].fill = RED_FILL
146 ws[f"C{row}"].fill = RED_FILL
147 ws[f"D{row}"].fill = RED_FILL
148 ws[f"E{row}"].fill = RED_FILL
149 ws[f"E{row}"] = res
150 continue
151
152 # ---------------- 执行SSH命令 ----------------
153 success, res = exec_ssh_command(ip, username, password, port, LINUX_COMMAND)
154 print(f"└─ ✅ 结果:{res[:80]}..." if len(res) > 80 else f"└─ ✅ 结果:{res}")
155
156 # ---------------- 写入结果 + 异常标红 ----------------
157 ws[f"E{row}"] = res
158 if not success:
159 ws[f"A{row}"].fill = RED_FILL
160 ws[f"B{row}"].fill = RED_FILL
161 ws[f"C{row}"].fill = RED_FILL
162 ws[f"D{row}"].fill = RED_FILL
163 ws[f"E{row}"].fill = RED_FILL
164
165 # 5. 保存文件
166 wb.save(result_file)
167 wb.close()
168 print(f"\n🎉 执行完成!所有结果已保存至:{result_file}")
169
170 # 全局异常处理,脚本永不崩溃
171 except FileNotFoundError:
172 print(f"❌ 错误:未找到 {SOURCE_EXCEL},请放在脚本同目录!")
173 except KeyError:
174 print("❌ 错误:Excel中没有 Sheet1 工作表!")
175 except PermissionError:
176 print("❌ 错误:Excel文件被打开,请关闭后重试!")
177 except Exception as e:
178 print(f"❌ 脚本异常:{str(e)}")
179
180if __name__ == "__main__":
181 main()ip.xlsx 格式(严格按照)工作表:Sheet1
| A1(ip) | B1(用户名) | C1(密码) | D1(端口) |
|---|---|---|---|
| 192.168.1.10 | root | 123456 | 22 |
| 192.168.1.11 | admin | abc123 | 2222 |
1LINUX_COMMAND = """
2你的Linux命令(支持特殊字符、多行、管道、变量)
3"""1python batch_server_run.pyip.xlsx Sheet1 读取:A=IP、B=用户、C=密码、D=端口result-2026-03-26_15:30:00.xlsx执行结果ip 执行成功!!! | 失败:ip 执行失败。。。以下情况整行标红并跳过,不中断批量执行:
完美支持:| && || $ 空格 中文 引号 等所有Linux特殊字符
示例:
1LINUX_COMMAND = """
2df -h | grep /dev
3free -h
4echo "当前目录:$PWD"
5systemctl stop firewalld
6"""ip.xlsx 和脚本放在同一个文件夹日历 · 精选 · 友链 · 更多
如果内容对你有帮助,欢迎请我喝杯咖啡 ☕



One的公众号
爱折腾博客的小白