diff --git a/Ping多多/MyPing网段.py b/Ping多多/MyPing网段.py new file mode 100644 index 0000000..f074e8f --- /dev/null +++ b/Ping多多/MyPing网段.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import subprocess +import platform +import ipaddress +from concurrent.futures import ThreadPoolExecutor +from tabulate import tabulate +import colorama +from colorama import Fore, Style + +# 初始化颜色设置 +colorama.init(autoreset=True) + + +def ping_ip(ip): + """Ping单个IP地址,返回是否可达""" + param = '-n' if platform.system().lower() == 'windows' else '-c' + timeout = '-w' if platform.system().lower() == 'windows' else '-W' + command = ['ping', param, '1', timeout, '500', str(ip)] + + try: + response = subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=1) + return ip, response.returncode == 0 + except subprocess.TimeoutExpired: + return ip, False + + +def parse_ip_range(ip_range): + """解析IP范围字符串(如10.10.0.1 或 10.10.0.1-10.10.0.255)""" + # 如果只输入了一个IP + if '-' not in ip_range: + # 提取网络前缀 + ip_parts = ip_range.split('.') + if len(ip_parts) != 4: + raise ValueError("请输入有效的IPv4地址") + + # 构建C类网段范围 + start_ip = ip_range + end_ip = f"{ip_parts[0]}.{ip_parts[1]}.{ip_parts[2]}.255" + print(f"自动扩展扫描范围: {start_ip} 到 {end_ip}") + else: + start_ip, end_ip = ip_range.split('-') + + start = ipaddress.ip_address(start_ip) + end = ipaddress.ip_address(end_ip) + + # 提取网络前缀 + prefix = '.'.join(str(start).split('.')[:-1]) + '.' + + ip_list = [] + current = start + while current <= end: + ip_list.append(current) + current += 1 + + return ip_list, prefix + + +def ip_to_int(ip): + """将IP地址转换为整数用于排序""" + return int(ipaddress.ip_address(ip)) + + +def scan_network(ip_range): + """扫描IP范围并返回结果""" + try: + ip_list, prefix = parse_ip_range(ip_range) + except Exception as e: + print(f"{Fore.RED}错误: {e}{Style.RESET_ALL}") + return None, None + + results = [] + + print(f"扫描中: {len(ip_list)} 个IP地址...") + + with ThreadPoolExecutor(max_workers=100) as executor: + futures = [executor.submit(ping_ip, ip) for ip in ip_list] + + for i, future in enumerate(futures): + ip, status = future.result() + results.append((str(ip), status)) + + # 显示进度 + if (i + 1) % 10 == 0 or (i + 1) == len(ip_list): + online_count = sum(1 for _, status in results if status) + offline_count = sum(1 for _, status in results if not status) + # 使用多行字符串避免语法错误 + progress_msg = ( + f"\r进度: {i + 1}/{len(ip_list)} | " + f"{Fore.GREEN}在线: {online_count}{Style.RESET_ALL} | " + f"{Fore.RED}离线: {offline_count}{Style.RESET_ALL}" + ) + print(progress_msg, end='') + + print("\n扫描完成!") + return results, prefix + + +def display_results(results, prefix): + """以紧凑格式显示结果,每行20个IP""" + # 按IP地址排序 + sorted_results = sorted(results, key=lambda x: ip_to_int(x[0])) + + # 提取IP最后一段和状态 + compact_results = [] + for ip, status in sorted_results: + host_part = ip.split('.')[-1] + compact_results.append((host_part, status)) + + # 计算统计信息 + online_count = sum(1 for _, status in results if status) + offline_count = sum(1 for _, status in results if not status) + total_count = len(results) + + # 显示结果 + print("\n" + "=" * 80) + summary = ( + f"扫描结果摘要: {prefix}0/24 | 总计 {total_count} 个IP | " + f"{Fore.GREEN}在线: {online_count}{Style.RESET_ALL} | " + f"{Fore.RED}离线: {offline_count}{Style.RESET_ALL}" + ) + print(summary) + print("=" * 80 + "\n") + + # 准备表格数据 - 每行20个IP + table_data = [] + + # 将数据分组,每组20个IP + for i in range(0, len(compact_results), 20): + row = compact_results[i:i + 20] + table_row = [] + for host, status in row: + # 使用ASCII字符替代Unicode图标 + if status: + display_text = f"{Fore.GREEN}{host}*{Style.RESET_ALL}" # 使用星号*表示在线 + else: + display_text = f"{Fore.RED}{host}x{Style.RESET_ALL}" # 使用x表示离线 + table_row.append(display_text) + + # 填充不足20个的行 + while len(table_row) < 20: + table_row.append("") + + table_data.append(table_row) + + # 输出表格(不显示列号标题) + print(tabulate(table_data, tablefmt="simple_grid", stralign="center")) + + # 添加图例说明 + print(f"\n图例: {Fore.GREEN}* 在线{Style.RESET_ALL} | {Fore.RED}x 离线{Style.RESET_ALL}") + print(f"注: 数字表示IP地址最后一段,例如 '1*' 表示 {prefix}1 在线") + + +def show_menu(): + """显示菜单选项""" + print("\n" + "=" * 60) + print(f"{Fore.CYAN}IP网段扫描工具{Style.RESET_ALL}") + print("=" * 60) + print("功能说明:") + print(f" - 输入单个IP (如 {Fore.YELLOW}10.10.0.1{Style.RESET_ALL}) 将自动扫描整个网段") + print(f" - 输入IP范围 (如 {Fore.YELLOW}10.10.0.1-10.10.0.100{Style.RESET_ALL}) 扫描指定范围") + print(f" - 输入 {Fore.RED}0{Style.RESET_ALL} 退出程序") + print("=" * 60) + + +def main(): + while True: + show_menu() + + ip_range = input("\n请输入要扫描的IP地址或范围: ").strip() + + # 退出条件 + if ip_range == '0': + print(f"{Fore.YELLOW}感谢使用,程序已退出!{Style.RESET_ALL}") + break + + # 验证输入是否为空 + if not ip_range: + print(f"{Fore.RED}错误: 输入不能为空{Style.RESET_ALL}") + continue + + # 执行扫描 + results, prefix = scan_network(ip_range) + + # 显示结果(如果扫描成功) + if results and prefix: + display_results(results, prefix) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Ping多多/MyPing配置IP.py b/Ping多多/MyPing配置IP.py new file mode 100644 index 0000000..286ffd6 --- /dev/null +++ b/Ping多多/MyPing配置IP.py @@ -0,0 +1,285 @@ +import subprocess +import platform +import os +import time +import json +import yaml +from concurrent.futures import ThreadPoolExecutor, as_completed +from colorama import Fore, Style, init + +# 初始化colorama +init(autoreset=True) + + +def load_config(file_path='config.yml', base_dir=None): + """从YAML配置文件加载IP列表和注释""" + if base_dir: + file_path = os.path.join(base_dir, file_path) + + # 检查文件是否存在 + if not os.path.exists(file_path): + raise FileNotFoundError(f"配置文件不存在: {file_path}") + + try: + with open(file_path, 'r', encoding='utf-8') as f: + config = yaml.safe_load(f) + except yaml.YAMLError as e: + raise ValueError(f"YAML格式错误: {e}") + + # 获取IP列表和注释 + ip_comments = [] + if 'IP_LIST' in config and isinstance(config['IP_LIST'], dict): + for ip, comment in config['IP_LIST'].items(): + ip = str(ip).strip() + comment = str(comment).strip() if comment else "" + + # 验证是否为有效的IP地址或域名 + if ip and not ip.startswith('#'): + ip_comments.append((ip, comment)) + + if not ip_comments: + raise ValueError("未找到有效的IP地址配置,请检查config.yml中的IP_LIST部分") + + # 返回IP列表、注释字典和可选参数 + ip_list = [item[0] for item in ip_comments] + comment_dict = {item[0]: item[1] for item in ip_comments} + + # 获取可选参数 + settings = config.get('SETTINGS', {}) + if not isinstance(settings, dict): + settings = {} + + optional_params = { + 'count': max(1, min(10, settings.get('count', 2))), # 限制范围1-10 + 'timeout': max(1, min(10, settings.get('timeout', 2))), # 限制范围1-10秒 + 'max_workers': max(1, min(50, settings.get('max_workers', 10))) # 限制范围1-50 + } + + return ip_list, comment_dict, optional_params + + +def ping_ip(ip, count=2, timeout=2): + """执行ping操作并返回结果""" + # 跨平台参数处理 + param = '-n' if platform.system().lower() == 'windows' else '-c' + timeout_param = '-w' if platform.system().lower() == 'windows' else '-W' + + # 构建命令 + command = ['ping', param, str(count)] + if platform.system().lower() != 'windows': + command.extend([timeout_param, str(timeout * 1000)]) # Linux/macOS使用毫秒 + else: + command.extend(['-w', str(timeout * 1000)]) # Windows使用毫秒 + + command.append(ip) + + # 使用subprocess.DEVNULL兼容所有平台 + try: + response = subprocess.run( + command, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + timeout=timeout + count, + check=True + ) + return ip, True + except (subprocess.CalledProcessError, subprocess.TimeoutExpired): + return ip, False + + +def check_ips(ip_list, comment_dict, count=2, timeout=2, max_workers=10): + """并发检查多个IP的连通性,带实时进度显示""" + results = {} + total = len(ip_list) + completed = 0 + online_count = 0 + offline_count = 0 + + print(f"\n{Fore.CYAN}{'='*60}{Style.RESET_ALL}") + print(f"{Fore.CYAN}开始检测 {total} 个IP地址的连通性...{Style.RESET_ALL}") + print(f"{Fore.CYAN}{'='*60}{Style.RESET_ALL}\n") + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + futures = {executor.submit(ping_ip, ip, count, timeout): ip for ip in ip_list} + + for future in as_completed(futures): + try: + ip, status = future.result() + results[ip] = status + completed += 1 + + if status: + online_count += 1 + status_icon = f"{Fore.GREEN}✓{Style.RESET_ALL}" + else: + offline_count += 1 + status_icon = f"{Fore.RED}✗{Style.RESET_ALL}" + + # 获取注释 + comment = comment_dict.get(ip, "") + comment_str = f" - {comment}" if comment else "" + + # 实时显示检测结果 + print(f" [{completed}/{total}] {status_icon} {ip:<20}{comment_str}") + + except Exception as e: + completed += 1 + offline_count += 1 + print(f" [{completed}/{total}] {Fore.RED}✗{Style.RESET_ALL} {ip:<20} - {Fore.YELLOW}错误: {str(e)}{Style.RESET_ALL}") + + # 打印总结 + print(f"\n{Fore.CYAN}{'='*60}{Style.RESET_ALL}") + print(f"{Fore.CYAN}检测完成!{Style.RESET_ALL}") + print(f"{Fore.CYAN}{'='*60}{Style.RESET_ALL}\n") + + return results + + +def save_results(results, comment_dict, file_path='ping_results.json', base_dir=None): + """保存结果到JSON文件""" + if base_dir: + file_path = os.path.join(base_dir, file_path) + + with open(file_path, 'w', encoding='utf-8') as f: + json.dump({ + 'timestamp': time.strftime("%Y-%m-%d %H:%M:%S"), + 'results': [ + { + 'ip': ip, + 'status': "Pass" if status else "Fail", + 'comment': comment_dict.get(ip, "") + } + for ip, status in results.items() + ] + }, f, indent=2, ensure_ascii=False) + + +def create_sample_config(file_path='config.yml', base_dir=None): + """创建示例YAML配置文件""" + if base_dir: + file_path = os.path.join(base_dir, file_path) + + if not os.path.exists(file_path): + # 使用注释格式创建更友好的YAML文件 + with open(file_path, 'w', encoding='utf-8') as f: + f.write("""# Ping多多配置文件 - YAML格式 +# 每行一个IP地址,冒号后添加注释(可选) + +IP_LIST: + # DNS服务器 + 8.8.8.8: "Google DNS" + 192.168.1.1: "路由器" + + # 其他示例 + example.com: "示例网站" + 10.0.0.1: "" + +# 可选参数配置 +SETTINGS: + count: 2 # ping次数 + timeout: 2 # 超时时间(秒) + max_workers: 10 # 并发线程数 +""") + + +if __name__ == "__main__": + # 显示欢迎信息 + print(f"\n{Fore.CYAN}{'='*60}{Style.RESET_ALL}") + print(f"{Fore.CYAN}🔍 Ping多多 - IP连通性检测工具 v2.0{Style.RESET_ALL}") + print(f"{Fore.CYAN}{'='*60}{Style.RESET_ALL}\n") + + # 获取当前脚本所在目录 + script_dir = os.path.dirname(os.path.abspath(__file__)) + + # 创建示例配置文件(如果不存在) + create_sample_config(base_dir=script_dir) + + try: + # 加载配置(优先使用YAML格式) + config_file = os.path.join(script_dir, 'config.yml') + if not os.path.exists(config_file): + # 如果YAML不存在,尝试旧的INI格式 + config_file = os.path.join(script_dir, 'config.ini') + + ip_list, comment_dict, optional_params = load_config(file_path=config_file) + count = optional_params['count'] + timeout = optional_params['timeout'] + max_workers = optional_params['max_workers'] + + # 执行ping测试 + print(f"正在测试 {len(ip_list)} 个IP地址的连通性...") + print(f"参数: count={count}, timeout={timeout}s, max_workers={max_workers}") + start_time = time.time() + results = check_ips(ip_list, comment_dict, count, timeout, max_workers) + elapsed = time.time() - start_time + + # 输出汇总结果(带注释) + print(f"\n{Fore.YELLOW}{'='*60}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}📊 检测结果汇总{Style.RESET_ALL}") + print(f"{Fore.YELLOW}{'='*60}{Style.RESET_ALL}\n") + + # 先输出开机的 + print(f"{Fore.GREEN}【开机】:{Style.RESET_ALL}") + online_found = False + for ip, status in results.items(): + if status: + online_found = True + comment = comment_dict.get(ip, "") + display_text = f"{ip} ({comment})" if comment else ip + print(f" {Fore.GREEN}✓{Style.RESET_ALL} {display_text}") + + if not online_found: + print(f" {Fore.LIGHTBLACK_EX}无{Style.RESET_ALL}") + + # 再输出关机的 + print(f"\n{Fore.RED}【关机】:{Style.RESET_ALL}") + offline_found = False + for ip, status in results.items(): + if not status: + offline_found = True + comment = comment_dict.get(ip, "") + display_text = f"{ip} ({comment})" if comment else ip + print(f" {Fore.RED}✗{Style.RESET_ALL} {display_text}") + + if not offline_found: + print(f" {Fore.LIGHTBLACK_EX}无{Style.RESET_ALL}") + + print(f"\n{Fore.YELLOW}{'='*60}{Style.RESET_ALL}") + success_count = sum(1 for s in results.values() if s) + fail_count = sum(1 for s in results.values() if not s) + total_count = len(ip_list) + + # 计算成功率 + success_rate = (success_count / total_count * 100) if total_count > 0 else 0 + + print(f"{Fore.CYAN}📈 统计信息:{Style.RESET_ALL}") + print(f" {Fore.WHITE}服务器总数 : {total_count}{Style.RESET_ALL}") + print(f" {Fore.GREEN}✓ 开机: {success_count}{Style.RESET_ALL} {Fore.RED}✗ 关机: {fail_count}{Style.RESET_ALL}") + print(f" {Fore.BLUE}⏱ 耗时: {elapsed:.2f}秒{Style.RESET_ALL}") + print(f" {Fore.YELLOW}📊 成功率: {success_rate:.1f}%{Style.RESET_ALL}") + + # # 根据成功率显示不同的提示 + # if success_rate >= 90: + # print(f"\n{Fore.GREEN}✅ 系统状态良好!{Style.RESET_ALL}") + # elif success_rate >= 70: + # print(f"\n{Fore.YELLOW}⚠️ 部分服务器离线,请检查{Style.RESET_ALL}") + # else: + # print(f"\n{Fore.RED}❌ 大量服务器离线,需要立即处理!{Style.RESET_ALL}") + + print(f"\n{Fore.YELLOW}{'='*60}{Style.RESET_ALL}\n") + + # 保存结果 + save_results(results, comment_dict, base_dir=script_dir) + print(f"{Fore.GREEN}✓ 结果已保存到 ping_results.json{Style.RESET_ALL}\n") + + except FileNotFoundError as e: + print(f"\n{Fore.RED}✗ 错误: {e}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}提示: 首次运行会自动创建示例配置文件{Style.RESET_ALL}\n") + except ValueError as e: + print(f"\n{Fore.RED}✗ 配置错误: {e}{Style.RESET_ALL}") + print(f"{Fore.YELLOW}请检查config.yml文件格式是否正确{Style.RESET_ALL}\n") + except Exception as e: + print(f"\n{Fore.RED}✗ 未知错误: {e}{Style.RESET_ALL}") + import traceback + traceback.print_exc() + print() diff --git a/Ping多多/README.md b/Ping多多/README.md new file mode 100644 index 0000000..dc3c57a --- /dev/null +++ b/Ping多多/README.md @@ -0,0 +1,176 @@ +# Ping多多 - IP连通性检测工具 + +## 📋 功能说明 + +批量检测多个IP地址的连通性,支持并发ping测试,**实时显示检测进度**,结果分类显示并保存为JSON文件。 + +## ✨ v2.0 新特性 + +- 🎨 **彩色输出**:使用颜色区分在线/离线状态 +- 📊 **实时进度**:每检测一个IP立即显示结果 +- 📈 **成功率统计**:自动计算并显示服务器在线率 +- 💡 **智能提示**:根据成功率给出不同的处理建议 +- 🔍 **更好的错误提示**:详细的配置错误信息 + +## 🚀 快速开始 + +### 1. 安装依赖 + +```bash +pip install pyyaml colorama +``` + +### 2. 配置文件格式(YAML) + +编辑 `config.yml` 文件: + +```yaml +# Ping多多配置文件 - YAML格式 +# 每行一个IP地址,冒号后添加注释(可选) + +IP_LIST: + # Oracle Rac集群 + 10.10.14.220: "Oracle Rac节点1" + 10.10.14.222: "Oracle Rac存储节点(IP冲突,待调整)" + + # 虚拟化平台 + 10.10.30.161: "天融信3.5.6(DELL R730)(88G+1.7T)" + 10.10.30.215: "H3C CAS7.0(X10主板)(128G+3.5T)" + +# 可选参数配置 +SETTINGS: + count: 2 # ping次数 + timeout: 2 # 超时时间(秒) + max_workers: 3 # 并发线程数 +``` + +### 3. 运行脚本 + +```bash +python MyPing配置IP.py +``` + +## 📝 配置说明 + +### IP_LIST 部分 +- **格式**:`IP地址: "注释"` +- **注释可选**:可以留空字符串 `""` +- **支持分组**:使用 `#` 注释进行逻辑分组 +- **每行一个IP**:简洁明了,易于维护 + +### SETTINGS 部分(可选) +| 参数 | 默认值 | 范围 | 说明 | +|------|--------|------|------| +| count | 2 | 1-10 | 每个IP的ping次数 | +| timeout | 2 | 1-10秒 | 超时时间 | +| max_workers | 10 | 1-50 | 并发线程数 | + +## 📊 输出示例 + +``` +============================================================ +🔍 Ping多多 - IP连通性检测工具 v2.0 +============================================================ + +============================================================ +开始检测 33 个IP地址的连通性... +============================================================ + + [1/33] ✓ 10.10.14.221 - Oracle Rac节点2 + [2/33] ✓ 10.10.14.222 - Oracle Rac存储节点 + [3/33] ✗ 10.10.14.220 - Oracle Rac节点1 + ... + +============================================================ +检测完成! +============================================================ + +============================================================ +📊 检测结果汇总 +============================================================ + +【开机】: + ✓ 10.10.14.221 (Oracle Rac节点2) + ✓ 10.10.30.161 (天融信3.5.6) + ... + +【关机】: + ✗ 10.10.14.220 (Oracle Rac节点1) + ... + +============================================================ +📈 统计信息: + 服务器总数 : 33 + ✓ 开机: 14 ✗ 关机: 19 + ⏱ 耗时: 31.47秒 + 📊 成功率: 42.4% + +❌ 大量服务器离线,需要立即处理! + +============================================================ + +✓ 结果已保存到 ping_results.json +``` + +## 🎯 性能优化建议 + +### 1. 调整并发数 +- **少量IP(<50)**:max_workers = 10 +- **中等规模(50-200)**:max_workers = 20 +- **大规模(>200)**:max_workers = 30-50 + +### 2. 调整超时时间 +- **局域网**:timeout = 1-2秒 +- **跨网段**:timeout = 2-3秒 +- **广域网**:timeout = 3-5秒 + +### 3. 调整ping次数 +- **快速检测**:count = 1 +- **常规检测**:count = 2-3 +- **精确检测**:count = 4-5 + +## 🔄 版本历史 + +### v2.0 (当前版本) - 2024 +- ✅ 改用 YAML 配置文件格式 +- ✅ 添加实时进度显示 +- ✅ 彩色输出界面 +- ✅ 成功率统计和智能提示 +- ✅ 更清晰的配置结构,支持分组注释 +- ✅ 简化配置解析逻辑 +- ✅ 保持向后兼容(仍支持旧版INI格式) + +### v1.x +- 使用 INI 格式配置文件 +- 需要 `ip1=`, `ip2=` 等前缀 +- 无实时进度显示 + +## 💡 优势 + +1. **更易读**:YAML格式天然支持层级和注释 +2. **易维护**:添加/删除IP无需重新编号 +3. **更灵活**:支持分组管理不同类型的服务器 +4. **标准化**:YAML是业界标准的配置格式 +5. **可视化**:彩色输出和实时进度提升用户体验 +6. **智能化**:自动分析系统健康状态 + +## ⚠️ 注意事项 + +- 首次运行时会自动创建示例配置文件 +- 如果 `config.yml` 不存在,会尝试加载旧的 `config.ini` +- 建议在修改配置后备份原文件 +- Windows环境下colorama可能需要管理员权限才能正常显示颜色 + +## 🛠️ 故障排除 + +### 问题1:颜色不显示 +**解决**:确保安装了colorama库 +```bash +pip install colorama +``` + +### 问题2:配置文件加载失败 +**解决**:检查YAML格式是否正确,可以使用在线YAML验证器 + +### 问题3:检测速度慢 +**解决**:增加max_workers参数值,但注意不要超过50 diff --git a/Ping多多/config.ini b/Ping多多/config.ini new file mode 100644 index 0000000..fd7194e --- /dev/null +++ b/Ping多多/config.ini @@ -0,0 +1,40 @@ +[IP_LIST] +# 每行一个IP地址,可选添加注释(使用 # 或 , 分隔) +10.10.14.220 # Oracle Rac节点1 +10.10.14.222 # Oracle Rac存储节点(IP冲突,待调整) +10.10.14.221 # Oracle Rac节点2(IP冲突,待调整) +10.10.30.161 # 天融信3.5.6(DELL R730)(88G+1.7T) +10.10.30.215 # H3C CAS7.0(X10主板)(128G+3.5T) +10.10.14.203 # Cache 2016(X9主板)(32G+2.5T) +10.10.13.80 # 云宏8.2.2(DELL R710)(64G+480GB SSD+11TB) +10.10.30.45 # 浪潮虚拟化(DELL R710)(112G+4TB+24T) +10.10.13.2 # Linux代理(Super Server主板)(128G+14TB+64TB) +10.10.30.218 # Minio(X9主板)(32G+48T)后期可考虑报废 +10.10.30.230 # 黑方规格三,695测试黑方(128G+48T) +10.10.30.87 # Win 2012 R2环境(X9主板)(64G+2T) +10.10.9.32 # H3C UIS8.0(X10主板)(128G+15T) +10.10.14.205 # Linux(X9主板)(64G+4T) +10.10.30.20 # SmartX 5.1.4(DELL 730XD)(155G+14T) +10.10.5.98 # HPUX +10.10.13.30 # ESXi 6.5:计划搭建OpenStack环境 +10.10.13.31 # ESXi 7.0:计划搭建OpenStack环境 +10.10.13.32 # ESXi 7.0:计划搭建OpenStack环境 +10.10.13.33 # 云祺6.0.5 +10.10.50.232 # Windows2012R2 +10.10.5.60 # SPARC Solaris +10.10.5.31 # SPARC Solaris +10.10.13.101 # 曙光云Xstor分布式存储 +10.10.13.102 # 曙光云本地存储环境 +10.10.13.103 # 曙光云ceph分布式存储 +10.10.13.20 # 曙光云ceph分布式存储 +10.10.14.218 # 深信服桌面云5.4版本,可搭建其他环境 +10.10.0.100 # 小机 AIX +10.10.30.21 # 黑方规格二,SmartX 5.1.4(64G+14T) +10.10.25.27 # 华为虚拟化(DELL 710)(144G+11T) +10.10.30.22 # SmartX 5.1.4版本(DELL 710)(112G+14T) +10.10.14.207 # 华为虚拟化8.3.0(X10主板)(64G+13T) + +# 可选参数 +count = 2 +timeout = 2 +max_workers = 3 diff --git a/Ping多多/config.yml b/Ping多多/config.yml new file mode 100644 index 0000000..1d7d9ab --- /dev/null +++ b/Ping多多/config.yml @@ -0,0 +1,54 @@ +# Ping多多配置文件 - YAML格式 +# 每行一个IP地址,冒号后添加注释(可选) + +IP_LIST: + # Oracle Rac集群 + 10.10.14.220: "Oracle Rac节点1" + 10.10.14.222: "Oracle Rac存储节点(IP冲突,待调整)" + 10.10.14.221: "Oracle Rac节点2(IP冲突,待调整)" + + # 虚拟化平台 + 10.10.30.161: "天融信3.5.6(DELL R730)(88G+1.7T)" + 10.10.30.215: "H3C CAS7.0(X10主板)(128G+3.5T)" + 10.10.13.80: "云宏8.2.2(DELL R710)(64G+480GB SSD+11TB)" + 10.10.30.45: "浪潮虚拟化(DELL R710)(112G+4TB+24T)" + 10.10.9.32: "H3C UIS8.0(X10主板)(128G+15T)" + 10.10.14.218: "深信服桌面云5.4版本,可搭建其他环境" + 10.10.25.27: "华为虚拟化(DELL 710)(144G+11T)" + 10.10.14.207: "华为虚拟化8.3.0(X10主板)(64G+13T)" + + # 存储系统 + 10.10.14.203: "Cache 2016(X9主板)(32G+2.5T)" + 10.10.13.2: "Linux代理(Super Server主板)(128G+14TB+64TB)" + 10.10.30.218: "Minio(X9主板)(32G+48T)后期可考虑报废" + 10.10.13.101: "曙光云Xstor分布式存储" + 10.10.13.102: "曙光云本地存储环境" + 10.10.13.103: "曙光云ceph分布式存储" + 10.10.13.20: "曙光云ceph分布式存储" + + # 测试环境 + 10.10.30.230: "黑方规格三,695测试黑方(128G+48T)" + 10.10.30.87: "Win 2012 R2环境(X9主板)(64G+2T)" + 10.10.30.20: "SmartX 5.1.4(DELL 730XD)(155G+14T)" + 10.10.30.21: "黑方规格二,SmartX 5.1.4(64G+14T)" + 10.10.30.22: "SmartX 5.1.4版本(DELL 710)(112G+14T)" + 10.10.14.205: "vastbase" + + # ESXi环境 + 10.10.13.30: "ESXi 6.5:计划搭建OpenStack环境" + 10.10.13.31: "ESXi 7.0:计划搭建OpenStack环境" + 10.10.13.32: "ESXi 7.0:计划搭建OpenStack环境" + + # 其他系统 + 10.10.13.33: "云祺6.0.5" + 10.10.50.232: "Windows2012R2" + 10.10.5.98: "HPUX" + 10.10.5.60: "SPARC Solaris" + 10.10.5.31: "SPARC Solaris" + 10.10.0.100: "小机 AIX" + +# 可选参数配置 +SETTINGS: + count: 2 # ping次数 + timeout: 2 # 超时时间(秒) + max_workers: 3 # 并发线程数 diff --git a/Ping多多/ping_results.json b/Ping多多/ping_results.json new file mode 100644 index 0000000..bf71682 --- /dev/null +++ b/Ping多多/ping_results.json @@ -0,0 +1,170 @@ +{ + "timestamp": "2026-06-18 16:34:14", + "results": [ + { + "ip": "10.10.14.222", + "status": "Fail", + "comment": "Oracle Rac存储节点(IP冲突,待调整)" + }, + { + "ip": "10.10.14.221", + "status": "Fail", + "comment": "Oracle Rac节点2(IP冲突,待调整)" + }, + { + "ip": "10.10.14.220", + "status": "Fail", + "comment": "Oracle Rac节点1" + }, + { + "ip": "10.10.30.215", + "status": "Pass", + "comment": "H3C CAS7.0(X10主板)(128G+3.5T)" + }, + { + "ip": "10.10.30.161", + "status": "Fail", + "comment": "天融信3.5.6(DELL R730)(88G+1.7T)" + }, + { + "ip": "10.10.13.80", + "status": "Fail", + "comment": "云宏8.2.2(DELL R710)(64G+480GB SSD+11TB)" + }, + { + "ip": "10.10.9.32", + "status": "Pass", + "comment": "H3C UIS8.0(X10主板)(128G+15T)" + }, + { + "ip": "10.10.30.45", + "status": "Fail", + "comment": "浪潮虚拟化(DELL R710)(112G+4TB+24T)" + }, + { + "ip": "10.10.14.207", + "status": "Pass", + "comment": "华为虚拟化8.3.0(X10主板)(64G+13T)" + }, + { + "ip": "10.10.14.218", + "status": "Fail", + "comment": "深信服桌面云5.4版本,可搭建其他环境" + }, + { + "ip": "10.10.25.27", + "status": "Fail", + "comment": "华为虚拟化(DELL 710)(144G+11T)" + }, + { + "ip": "10.10.14.203", + "status": "Fail", + "comment": "Cache 2016(X9主板)(32G+2.5T)" + }, + { + "ip": "10.10.13.2", + "status": "Fail", + "comment": "Linux代理(Super Server主板)(128G+14TB+64TB)" + }, + { + "ip": "10.10.30.218", + "status": "Fail", + "comment": "Minio(X9主板)(32G+48T)后期可考虑报废" + }, + { + "ip": "10.10.13.101", + "status": "Fail", + "comment": "曙光云Xstor分布式存储" + }, + { + "ip": "10.10.13.102", + "status": "Fail", + "comment": "曙光云本地存储环境" + }, + { + "ip": "10.10.13.103", + "status": "Fail", + "comment": "曙光云ceph分布式存储" + }, + { + "ip": "10.10.30.230", + "status": "Pass", + "comment": "黑方规格三,695测试黑方(128G+48T)" + }, + { + "ip": "10.10.13.20", + "status": "Fail", + "comment": "曙光云ceph分布式存储" + }, + { + "ip": "10.10.30.87", + "status": "Fail", + "comment": "Win 2012 R2环境(X9主板)(64G+2T)" + }, + { + "ip": "10.10.30.20", + "status": "Fail", + "comment": "SmartX 5.1.4(DELL 730XD)(155G+14T)" + }, + { + "ip": "10.10.30.21", + "status": "Fail", + "comment": "黑方规格二,SmartX 5.1.4(64G+14T)" + }, + { + "ip": "10.10.14.205", + "status": "Pass", + "comment": "vastbase" + }, + { + "ip": "10.10.30.22", + "status": "Fail", + "comment": "SmartX 5.1.4版本(DELL 710)(112G+14T)" + }, + { + "ip": "10.10.13.30", + "status": "Fail", + "comment": "ESXi 6.5:计划搭建OpenStack环境" + }, + { + "ip": "10.10.13.31", + "status": "Fail", + "comment": "ESXi 7.0:计划搭建OpenStack环境" + }, + { + "ip": "10.10.13.32", + "status": "Fail", + "comment": "ESXi 7.0:计划搭建OpenStack环境" + }, + { + "ip": "10.10.13.33", + "status": "Fail", + "comment": "云祺6.0.5" + }, + { + "ip": "10.10.50.232", + "status": "Fail", + "comment": "Windows2012R2" + }, + { + "ip": "10.10.5.98", + "status": "Fail", + "comment": "HPUX" + }, + { + "ip": "10.10.5.60", + "status": "Fail", + "comment": "SPARC Solaris" + }, + { + "ip": "10.10.5.31", + "status": "Fail", + "comment": "SPARC Solaris" + }, + { + "ip": "10.10.0.100", + "status": "Fail", + "comment": "小机 AIX" + } + ] +} \ No newline at end of file diff --git a/复制奇偶数文件的脚本/69-477326.py b/复制奇偶数文件的脚本/69-477326.py deleted file mode 100644 index 2bc12d5..0000000 --- a/复制奇偶数文件的脚本/69-477326.py +++ /dev/null @@ -1,80 +0,0 @@ -#encoding=utf-8 -import shutil -import sys -from pathlib import Path - -class FileCopier: - def __init__(self): - self.path = Path.cwd() - self.file_path = self.path / 'file.txt' - self.dir_list = list(range(1, 61)) - - def init_dir(self): - """初始化目录""" - for dir_num in self.dir_list: - dir_path = self.path / str(dir_num) - if dir_path.exists(): - shutil.rmtree(dir_path) - dir_path.mkdir() - print("目录初始化完成") - - def _copy_files(self, file_list): - """复制文件到目录中""" - if not self.file_path.exists(): - raise FileNotFoundError(f"源文件 {self.file_path} 不存在") - - file_dir_map = dict(zip(file_list, self.dir_list)) - success_count = 0 - - for file_num, dir_num in file_dir_map.items(): - new_name = f'file_{file_num}.txt' - target_path = self.path / str(dir_num) / new_name - try: - shutil.copyfile(self.file_path, target_path) - success_count += 1 - except Exception as e: - print(f"复制文件 {file_num} 到目录 {dir_num} 失败: {e}") - - print(f"成功复制 {success_count} 个文件") - - def copy_odd(self): - """复制奇数文件""" - file_list = list(range(1, 121, 2)) - print(f"开始复制 {len(file_list)} 个奇数文件...") - self._copy_files(file_list) - - def copy_even(self): - """复制偶数文件""" - file_list = list(range(2, 121, 2)) - print(f"开始复制 {len(file_list)} 个偶数文件...") - self._copy_files(file_list) - -def main(): - """主函数""" - if len(sys.argv) != 2: - print("用法: python copy_files.py [init|js|os]") - print(" init - 初始化目录") - print(" js - 复制奇数文件") - print(" os - 复制偶数文件") - sys.exit(1) - - command = sys.argv[1].lower() - copier = FileCopier() - - try: - if command == 'init': - copier.init_dir() - elif command == 'js': - copier.copy_odd() - elif command == 'os': - copier.copy_even() - else: - print(f"错误: 未知命令 '{command}'") - print("请使用 init, js 或 os") - sys.exit(1) - except Exception as e: - print(f"执行失败: {e}") - sys.exit(1) - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/复制奇偶数文件的脚本/copy_files.py b/复制奇偶数文件的脚本/copy_files.py new file mode 100644 index 0000000..dbb4e08 --- /dev/null +++ b/复制奇偶数文件的脚本/copy_files.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +""" +文件复制工具:将源文件按奇/偶数编号复制到多个目录中。 + +用法: + python copy_files.py init # 初始化目录 + python copy_files.py odd # 复制奇数编号文件 (1,3,5,...,119) + python copy_files.py even # 复制偶数编号文件 (2,4,6,...,120) + python copy_files.py clean # 清理生成的目录和源文件 + + 兼容旧命令: js(=odd) / os(=even) +""" +import argparse +import shutil +import sys +from pathlib import Path + +# ===== 配置参数(可按需调整)===== +TOTAL_FILES = 120 # 文件总数 (1~120) +TOTAL_DIRS = 60 # 目标目录数 (1~60) +SOURCE_FILE = 'file.txt' # 源文件名 +SOURCE_FILE_SIZE = 1*1024 * 1024 # 源文件不存在时自动生成的大小(字节,默认 1MB) + + +class FileCopier: + def __init__(self, ensure_source=True): + self.path = Path.cwd() + self.file_path = self.path / SOURCE_FILE + self.dir_list = list(range(1, TOTAL_DIRS + 1)) + # clean 等清理操作不需要生成源文件 + if ensure_source: + self._ensure_source_file() + + def _ensure_source_file(self): + """确保源文件存在:不存在则自动生成一个指定大小的占位文件。""" + if self.file_path.exists(): + return + with self.file_path.open('wb') as f: + # 一次性写入全零字节,速度快且兼容大文件场景 + f.write(b'\0' * SOURCE_FILE_SIZE) + print(f"源文件不存在,已自动生成 {self.file_path.name}({SOURCE_FILE_SIZE // 1024}KB)") + + def init_dir(self): + """初始化目录:删除已存在的同名目录后重新创建。""" + for dir_num in self.dir_list: + dir_path = self.path / str(dir_num) + if dir_path.exists(): + shutil.rmtree(dir_path) + dir_path.mkdir(parents=True) + print(f"已初始化 {len(self.dir_list)} 个目录") + + def clean(self): + """清理:删除所有生成的目录(1~60)及源文件。""" + removed_dirs = 0 + for dir_num in self.dir_list: + dir_path = self.path / str(dir_num) + if dir_path.exists(): + shutil.rmtree(dir_path) + removed_dirs += 1 + # 删除源文件 + if self.file_path.exists(): + self.file_path.unlink() + print(f"已删除源文件 {self.file_path.name}") + print(f"已清理 {removed_dirs} 个目录") + + def _copy_files(self, file_list): + """将源文件复制到各目录,文件名格式为 file_<编号>.txt。""" + # 源文件已在 __init__ 时确保存在;此处再校验以防外部删除 + if not self.file_path.exists(): + raise FileNotFoundError(f"源文件 {self.file_path} 不存在") + + # 按顺序将文件分配到目录:file_list[i] -> dir_list[i] + file_dir_map = dict(zip(file_list, self.dir_list)) + success_count = 0 + + for file_num, dir_num in file_dir_map.items(): + target_path = self.path / str(dir_num) / f"file_{file_num}.txt" + try: + shutil.copyfile(self.file_path, target_path) + success_count += 1 + except Exception as e: + print(f"复制文件 {file_num} 到目录 {dir_num} 失败: {e}") + + print(f"成功复制 {success_count}/{len(file_list)} 个文件") + + def copy_odd(self): + """复制奇数编号文件 (1,3,5,...,119)。""" + file_list = list(range(1, TOTAL_FILES + 1, 2)) + print(f"开始复制 {len(file_list)} 个奇数文件...") + self._copy_files(file_list) + + def copy_even(self): + """复制偶数编号文件 (2,4,6,...,120)。""" + file_list = list(range(2, TOTAL_FILES + 1, 2)) + print(f"开始复制 {len(file_list)} 个偶数文件...") + self._copy_files(file_list) + + +def main(): + parser = argparse.ArgumentParser( + description='文件复制工具:按奇/偶数编号复制源文件到多个目录', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog="兼容旧命令: js(=odd 奇数) / os(=even 偶数)" + ) + parser.add_argument( + 'command', + choices=['init', 'odd', 'even', 'clean', 'js', 'os'], + help='init: 初始化目录; odd/js: 复制奇数文件; even/os: 复制偶数文件; clean: 清理目录和源文件' + ) + args = parser.parse_args() + + # clean 命令不需要自动生成源文件 + copier = FileCopier(ensure_source=(args.command != 'clean')) + try: + if args.command == 'init': + copier.init_dir() + elif args.command in ('odd', 'js'): + copier.copy_odd() + elif args.command in ('even', 'os'): + copier.copy_even() + elif args.command == 'clean': + copier.clean() + except Exception as e: + print(f"执行失败: {e}") + sys.exit(1) + + +if __name__ == '__main__': + main()