10.26

 这个世界上有太多的人,我们不能一一去比较,那样不仅太累而且没有什么意义。

你所做的就是做好当下的事,一步步向前,在这个过程中,可能会有不如意,会有抱怨,会有不甘心。

但这个世界总会在将来给你更好的。

在这个时代,只要你把某件事做到很好,机会会找上你。

你会拥有一切。

向前吧!不要停止你的步伐。

不要为昨天而烦恼,过好今天,向着未来,昨天的失去可是让你得到以后更好的!

# ********************************************************** # Copyright (c) 2019, YANGTZE MEMORY TECHNOLOGIES CO. LTD. # File: utp_tester_update_all # Create Date: 2024/05/20 # Creator: Xiangshi_Yan # ********************************************************** import os import re import sys import time import glob import shutil import logging import zipfile import paramiko import threading import socket import subprocess from paramiko import SSHClient from paramiko import AuthenticationException from paramiko.client import SSHClient,AutoAddPolicy from paramiko.ssh_exception import NoValidConnectionsError port_list = [] device_info_dict = {} support_input_sg_list = [] adb_check_failed_ips = [] # 用于选项3、4的ADB升级失败记录 adb_check_success_ips_9_10 = [] # 用于选项9:记录ADB版本检查成功的IP adb_check_failed_ips_9_10 = [] # 用于选项9:记录ADB版本检查失败的IP offline_recovery_report = [] # 在代码开头定义预定义IP列表 PREDEFINED_IP_LISTS = { "list1": ["10.26.92.219"], "list2": ["10.26.92.219"] } USERNAME = "mobile01" PASSWORD = "123456" # logging.basicConfig(format = "%(asctime)s | %(levelname)s | %(name)s | %(message)s", # level=logging.DEBUG) # outside_path = None outside_path = '/share_ufs_code/User_Test_Flow/utp/00_utp_tester_update_sdk_fw/' fw_update_path = 'V2.12.2' full_relative_path = os.path.join(outside_path, fw_update_path) bash_path = '__base_shell' bash_relative_path = os.path.join(outside_path, bash_path) sn_modify_path = 'sn_modify_tool' sn_relative_path = os.path.join(outside_path, sn_modify_path) utp_data_tester_path = '/data/tester' utp_sh_file = os.path.join(utp_data_tester_path, 'sn_modify_tool.sh') # 新增函数:线程安全的任务执行器 def execute_tasks_with_thread_limit(ip_list, task_func, *args, max_threads=10): """执行任务时限制同时运行的线程数量""" threads = [] results = [] # 用于存储任务结果 for ip in ip_list: # 如果当前线程数达到上限,等待部分线程完成 while threading.active_count() > max_threads: time.sleep(0.5) # 创建并启动新线程 t = threading.Thread(target=task_func, args=(ip, *args)) t.start() threads.append(t) # 等待所有线程完成 for t in threads: t.join() return results def check_and_recover_offline_devices(client, hostname): """检查并尝试恢复离线设备,返回恢复结果列表""" results = [] print(f"🔍 {hostname}: 检查设备连接状态...") # 获取设备列表 _, stdout, stderr = client.exec_command("adb devices -l") time.sleep(2) adb_devices_output = stdout.read().decode() + stderr.read().decode() # 解析设备状态 all_devices = [] # 存储所有设备ID online_devices = [] # 存储在线设备ID offline_devices = [] # 存储离线设备ID for line in adb_devices_output.splitlines(): if "List of devices" in line or line.strip() == "": continue parts = line.split() if len(parts) >= 2: device_id = parts[0] status = parts[1] all_devices.append(device_id) if status == "offline": offline_devices.append(device_id) elif status == "device": online_devices.append(device_id) else: print(f"⚠️ {hostname}: 无法解析设备行: {line}") # 显示设备总数 total_devices = len(all_devices) print(f"\n📊 {hostname}: 检测到 {total_devices} 台设备") # 先记录所有在线设备的状态为“在线” for device in online_devices: results.append({ "ip": hostname, "device": device, "status": "在线" }) # 处理离线设备 if offline_devices: print(f"⚠️ {hostname}: 发现 {len(offline_devices)} 个离线设备") for device in offline_devices: print(f" - 尝试恢复设备 {device}...") # 重试逻辑 recovered = False for attempt in range(1, 4): try: reconnect_cmd = f"adb -s {device} reconnect" client.exec_command(reconnect_cmd) time.sleep(2) # 检查重连结果 _, stdout, stderr = client.exec_command(f"adb -s {device} get-state") state = stdout.read().decode().strip() if state == "device": print(f"✅ {hostname}: 设备 {device} 恢复在线") recovered = True results.append({ "ip": hostname, "device": device, "status": "成功恢复" }) break else: print(f"⚠️ {hostname}: 设备 {device} 恢复失败 (尝试 {attempt}/3)") except Exception as e: print(f"❌ {hostname}: 设备 {device} 重连异常 - {str(e)}") if not recovered: print(f"❌ {hostname}: 设备 {device} 无法恢复") results.append({ "ip": hostname, "device": device, "status": "恢复失败" }) else: print(f"✅ {hostname}: 所有设备在线") # 如果没有设备,添加占位记录 if total_devices == 0: results.append({ "ip": hostname, "device": "N/A", "status": "未检测到设备" }) print(f"⚠️ {hostname}: 未检测到任何设备") return results def check_adb_version(hostname, username, password): """检查指定主机的ADB版本""" client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: # 尝试连接主机 client.connect(hostname, port=22, username=username, password=password, timeout=3) print(f"✅ {hostname}: 连接成功") # 执行ADB版本检查命令 command = "adb version" print(f"🔍 {hostname}: 执行ADB版本检查...") _, stdout, stderr = client.exec_command(command) # 等待命令完成 start_time = time.time() while not stdout.channel.exit_status_ready(): if time.time() - start_time > 10: # 10秒超时 print(f"⏱️ {hostname}: ADB版本检查超时") return False time.sleep(0.5) # 获取执行结果 exit_status = stdout.channel.recv_exit_status() output = stdout.read().decode() + stderr.read().decode() # 分析输出结果 version_match = re.search(r"version\s+(\d+\.\d+\.\d+)", output) if version_match: version = version_match.group(1) if version == "1.0.39": print(f"✅ {hostname}: ADB版本正确 (1.0.39)") return True else: print(f"⚠️ {hostname}: ADB版本不正确 (当前: {version}, 需要: 1.0.39)") return False elif "command not found" in output: print(f"❌ {hostname}: ADB未安装") return False else: print(f"❌ {hostname}: 无法识别ADB版本") print(f"详细输出: {output[:300]}") return False except AuthenticationException: print(f"❌ {hostname}: 认证失败,请检查用户名/密码") return False except NoValidConnectionsError: print(f"❌ {hostname}: 无法连接,可能是网络问题或主机未开启") return False except socket.timeout: print(f"❌ {hostname}: 连接超时") return False except Exception as e: print(f"❌ {hostname}: 连接错误 - {str(e)}") return False finally: try: client.close() except: pass def update_and_check_adb(client, hostname, password, check_only=False): """ 更新并检查ADB版本 :param check_only: 如果为True,仅检查版本不执行升级 """ try: # 创建SFTP客户端上传脚本(仅在需要升级时上传) if not check_only: sftp = client.open_sftp() local_script_path = './adb_1039.sh' remote_script_path = '/tmp/adb_1039.sh' sftp.put(local_script_path, remote_script_path) sftp.chmod(remote_script_path, 0o755) sftp.close() print(f"✅ {hostname}: 已上传adb_1039.sh") # 准备执行的命令 if check_only: command = "adb version" # 仅检查版本 print(f"🔍 {hostname}: 检查ADB版本...") else: command = f"echo '{password}' | sudo -S sh /tmp/adb_1039.sh" # 升级命令 print(f"🔧 {hostname}: 执行ADB升级命令...") # 执行命令 _, stdout, stderr = client.exec_command(command) # 等待命令完成 start_time = time.time() while not stdout.channel.exit_status_ready(): if time.time() - start_time > (30 if check_only else 60): # 检查模式30秒超时,升级模式60秒 print(f"⏱️ {hostname}: 操作超时") return False time.sleep(1) exit_status = stdout.channel.recv_exit_status() output = stdout.read().decode() + stderr.read().decode() # 检查升级结果 - 区分两种情况 if check_only: # 仅检查模式下的输出解析 version_match = re.search(r"version\s+(\d+\.\d+\.\d+)", output) if version_match: version = version_match.group(1) if version == "1.0.39": print(f"✅ {hostname}: ADB版本正确 (1.0.39)") return True else: print(f"⚠️ {hostname}: ADB版本不正确 (当前: {version}, 需要: 1.0.39)") return False elif "command not found" in output: print(f"❌ {hostname}: ADB未安装") return False else: print(f"❌ {hostname}: 无法识别ADB版本") print(f"详细输出: {output[:300]}") return False else: success_strings = [ "adb version 1.0.39 have install [OK]", "adb version is already 1.0.39"] # 检查是否包含任何成功标志 if any(success_str in output for success_str in success_strings): print(f"✅ {hostname}: ADB升级成功 (1.0.39)") return True else: # 使用同一个SSH连接直接检查版本 version_ok = False try: # 使用同一个SSH连接执行版本检查 _, stdout, stderr = client.exec_command("adb version") # 等待命令完成 start_time = time.time() while not stdout.channel.exit_status_ready(): if time.time() - start_time > 10: # 10秒超时 break time.sleep(0.5) adb_output = stdout.read().decode() + stderr.read().decode() version_match = re.search(r"version\s+(\d+\.\d+\.\d+)", adb_output) if version_match: version = version_match.group(1) if version == "1.0.39": print(f"✅ {hostname}: 版本检查确认ADB已升级成功 (1.0.39)") version_ok = True except Exception as e: print(f"❌ {hostname}: 版本检查失败 - {str(e)}") if version_ok: return True else: print(f"❌ {hostname}: ADB升级失败 (退出码: {exit_status})") # ... [保留错误诊断代码] ... return False except Exception as e: print(f"❌ {hostname}: 操作异常 - {str(e)}") return False def input_information(): # 不再询问用户名和密码,直接使用全局常量 base_ip = '10.26.92' # 保留IP前缀默认值 start = int(input("输入ip第四段的开始字段(例如10.26.92.228的228): ")) end = int(input("输入ip第四段的结束字段: ")) logging.info(f"Input base_ip:{base_ip}, start~end:{start}~{end}") return base_ip, start, end def generate_ip_range(start, end, base_ip): ips = [] for i in range(start, end + 1): ip_str = f"{base_ip}.{i}" ips.append(ip_str) return ips def unzip_files(directory): """check utp zip file""" for filename in os.listdir(directory): file_path = os.path.join(directory, filename) if file_path.endswith('.zip') and 'UTP' in file_path: logging.info(f'\033[1;31m=========01-找到UTP的压缩包--{file_path} verify OK!!=========\033[0m') return filename elif file_path.endswith('.zip'): logging.info("=========unzip,waitting...=========") with zipfile.ZipFile(file_path, 'r') as zip_ref: zip_ref.extractall(directory) print(f'Extracted {file_path} to {directory}') else: logging.info(f'{file_path} is not a zip file.') def check_files(path): zip_count = 0 sh_count = 0 for filename in os.listdir(path): # Check suffix to determine file type. file_extension = os.path.splitext(filename)[1] if file_extension == '.zip': zip_count += 1 elif file_extension in ['.sh', '.SH']: sh_count += 1 if zip_count in (1, 2) and sh_count in (0, 1): logging.info(f"=========sh的数量是{sh_count}个(2个),数量不对,执行copy=========") return 2 logging.info(f"=========sh的数量是{sh_count}个(2个)=========") return zip_count in (1, 2) and sh_count == 2 def del_all_sh(path): sh_files = glob.glob(os.path.join(path, '*.sh')) for sh_file in sh_files: os.remove(sh_file) def copy_all_sh(path, path2): sh_files = glob.glob(os.path.join(path, '*.sh')) for sh_file in sh_files: filename = os.path.basename(sh_file) shutil.copyfile(sh_file, os.path.join(path2, filename)) def get_utp_port(): number = 100 print("\n\n") logging.info("=========识别 UTP3.1 Tester=========") try: logging.info("扫描当前的UTP3.1 Tester, 执行命令: adb device -l") result = subprocess.run(['adb', 'devices', '-l'], capture_output=True, text=True) if int(result.returncode) == 0: # 执行成功 out_str = result.stdout out_str_list = out_str.split("\n") for out_str in out_str_list: if " device usb:" in out_str: logging.info("设备: {}".format(out_str)) if "0123456789ABCDEF" in out_str: support_input_sg_list.append(99) m1 = re.search("device\s(.*?)\s", out_str) device_info_dict.update({99: m1.group(1)}) elif "0123456789N1Y" in out_str: m0 = re.search("0123456789N1Y(\d+)", out_str) m1 = re.search("device\s(.*?)\s", out_str) if m0 and m1: device_info_dict.update({int(m0.group(1)): m1.group(1)}) support_input_sg_list.append(int(m0.group(1))) else: number = number+1 support_input_sg_list.append(number) m1 = re.search("device\s(.*?)\s", out_str) device_info_dict.update({number: m1.group(1)}) except: logging.info("扫描当前的UTP3.1 Tester, 失败, 请确认是否能正常运行 adb devices命令") return logging.info("请输入需要被选中的Tester当前Port号") logging.info(" 1~15: 表示选择0123456789N1Y001 ~ 0123456789N1Y015") logging.info(" 99: 表示选择0123456789ABCDEF") logging.info(" 100以上为未烧录UTP: 表示选择未烧录utp") sorted_list = list(set(support_input_sg_list)) sorted_list = sorted(sorted_list) # log.info(" 可支持输入的Port号对应的device信息为: {}".format(device_info_dict)) logging.info(" 可支持输入的Port号为: {}".format(sorted_list)) print(" 可支持输入的Port号为: {}.输入100对全部进行选中".format(sorted_list)) logging.info(" 可支持输入多个Port号, 如 1, 3, 5") logging.info(" 可支持对所有Port号进行输入, 请输入100") input_value = input() input_value_list = list(map(int, input_value.split(','))) if len(input_value_list) == 1 and input_value_list[0] == 100: input_value_list = sorted_list logging.info("需要被选中的UTP Tester Port号为 {}".format(input_value_list)) for input_value in input_value_list: if input_value not in support_input_sg_list: logging.info("你输入的Port号:{}, 不对应任何tester, 请检查".format(input_value)) return else: port_string = ' ' device_info = device_info_dict[input_value] port_list.append(device_info) logging.info("你输入的Port号为:{}, 对应的device info为:{}".format(input_value, device_info)) # logging.info(f'{type(device_info)}') if support_input_sg_list.count(input_value) != 1: logging.info("你输入的Port号:{}, 对应多个tester, 请检查".format(input_value)) return result = port_string.join(port_list) #logging.info(f'device_info_dict:{device_info_dict},input_value:{input_value},input_value_list{input_value_list},result:{result}') return device_info_dict, input_value, input_value_list, result def connect_with_ssh(hostname, username, password, choice): client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname, port=22, username=username, password=password, timeout=3) channel = client.invoke_shell() if cp == 12: try: print(f"hostname: {hostname}") stdin, stdout, stderr = client.exec_command('adb devices -l') devices_output = stdout.read().decode() for device_line in devices_output.strip().split('\n')[1:]: device_serial = device_line.split(' ')[0] print(f"Rebooting device: {device_serial}") client.exec_command(f'adb -s {device_serial} reboot') time.sleep(0.5) except Exception as e: print(f"Error: {e}") sys.exit(0) if choice == 9: adb_ok = update_and_check_adb(client, hostname, password, check_only=True) if adb_ok: adb_check_success_ips_9_10.append(hostname) else: adb_check_failed_ips_9_10.append(hostname) client.close() return adb_ok # 选项10:仅升级ADB elif choice == 10: adb_ok = update_and_check_adb(client, hostname, password) if adb_ok: adb_check_success_ips_9_10.append(hostname) else: adb_check_failed_ips_9_10.append(hostname) client.close() return adb_ok # 选项11:仅Check offline if choice == 11: try: print(f"🔍 {hostname}: 开始离线设备检测...") results = check_and_recover_offline_devices(client, hostname) # 将结果添加到全局报告 offline_recovery_report.extend(results) # 输出当前IP的检测结果 print(f"📊 {hostname} 设备状态报告:") for result in results: status_icon = "✅" if "成功" in result["status"] or "在线" in result["status"] else "❌" print(f" {status_icon} Device: {result['device']} | 状态: {result['status']}") client.close() return except Exception as e: print(f"❌ {hostname}: 检测失败 - {str(e)}") offline_recovery_report.append({ "ip": hostname, "device": "N/A", "status": f"检测失败: {str(e)}" }) finally: try: client.close() except: pass return # 在升级前检查设备状态(仅对升级操作) if choice in [3, 4]: print(f"🔍 {hostname}: 检查设备连接状态...") # 使用标准adb devices命令检测设备状态 _, stdout, stderr = client.exec_command("adb devices") time.sleep(1) # 等待命令执行 adb_devices_output = stdout.read().decode() + stderr.read().decode() # 解析设备状态 (更可靠的解析方法) offline_devices = [] for line in adb_devices_output.splitlines(): # 跳过标题行和设备列表结束行 if "List of devices" in line or line.strip() == "": continue # 设备行的标准格式: [device_id] [status] parts = line.split() if len(parts) >= 2: device_id = parts[0] status = parts[1] if status == "offline": offline_devices.append(device_id) # 处理离线设备 if offline_devices: print(f"⚠️ {hostname}: 发现 {len(offline_devices)} 个离线设备") for device in offline_devices: print(f" - 尝试恢复设备 {device}...") # 重试逻辑 max_retries = 3 recovered = False for attempt in range(1, max_retries + 1): try: # 执行重连命令 reconnect_cmd = f"adb -s {device} reconnect" _, stdout, stderr = client.exec_command(reconnect_cmd) time.sleep(2) # 等待重连 # 检查重连结果 - 使用adb devices确认状态 _, stdout, stderr = client.exec_command("adb devices") time.sleep(1) devices_output = stdout.read().decode() # 检查设备是否恢复在线 device_line = next((line for line in devices_output.splitlines() if device in line and "device" in line), None) if device_line: print(f"✅ {hostname}: 设备 {device} 恢复在线") recovered = True break else: print(f"⚠️ {hostname}: 设备 {device} 恢复失败 (尝试 {attempt}/{max_retries})") except Exception as e: print(f"❌ {hostname}: 设备 {device} 重连异常 - {str(e)}") if not recovered: print(f"❌ {hostname}: 设备 {device} 无法恢复,将跳过") else: print(f"✅ {hostname}: 所有设备在线") # 仅针对升级操作(choice 3或4)执行ADB检查 if choice in [3, 4]: adb_ok = update_and_check_adb(client, hostname, password) if not adb_ok: print(f"⏩ {hostname}: 跳过UTP升级(ADB版本不符合要求)") adb_check_failed_ips.append(hostname) client.close() return else: print(f"✅ {hostname}: ADB版本符合要求,继续UTP升级") print("ip:%s connecting,please wait for 900 s......"%hostname) channel.send('ifconfig\n whoami \n adb devices -l \n') time.sleep(1) channel.send('su -\n') time.sleep(1) channel.send('{}\n'.format(password)) time.sleep(1) channel.send('whoami \n') time.sleep(1) # 如果 ADB 升级成功,继续执行UTP升级 if choice == 1: channel.send('cd {} \n UTPVERSION="3.1" ./utp_update.sh check_version\n'.format(full_relative_path)) time.sleep(1) elif choice == 2: device_info_dict,input_value,input_value_list, result = get_utp_port() print(result) channel.send('cd {} \n UTPVERSION="3.1" ./utp_update.sh check_version {}\n'.format(full_relative_path, result)) time.sleep(1) elif choice == 3: device_info_dict,input_value,input_value_list, result = get_utp_port() channel.send('cd {} \n UTPVERSION="3.1" ./utp_update.sh all {} {}\n'.format(full_relative_path, utp_zip_name, result)) time.sleep(1) elif choice == 4: # 对于选项4,获取所有在线设备 _, stdout, stderr = client.exec_command("adb devices") time.sleep(1) adb_devices_output = stdout.read().decode() + stderr.read().decode() # 解析所有在线的设备ID online_devices = [] for line in adb_devices_output.splitlines(): if "List of devices" in line or line.strip() == "": continue parts = line.split() if len(parts) >= 2 and parts[1] == "device": online_devices.append(parts[0]) if online_devices: result = ' '.join(online_devices) print(f"✅ {hostname}: 将升级的设备: {result}") # channel.send('cd {} \n UTPVERSION="3.1" ./utp_update.sh all {}\n'.format(full_relative_path, utp_zip_name)) channel.send('cd {} \n UTPVERSION="3.1" ./utp_update.sh all {} {}\n'.format(full_relative_path, utp_zip_name, result)) time.sleep(1) else: print(f"⏩ {hostname}: 没有在线设备,跳过UTP升级") client.close() return else: logging.info("无效的输入") exit() # 等待UTP升级完成 for i in range(1800): time.sleep(1) output = "" while channel.recv_ready(): output += channel.recv(1024*1024).decode() if output: print(output) if "host_sdk_version:" in output: logging.info(f'\033[1;31m=========04-IP:{hostname} checkversion finished=========\033[0m') print(f'\033[1;31mIP:{hostname} checkversion finished\033[0m') break channel.close() return client.close() def push_file_to_device(local_path, remote_path, usb): files = [os.path.join(local_path, f) for f in os.listdir(local_path) if os.path.isfile(os.path.join(local_path, f))] for file in files: command = ['adb', '-s', usb, 'push', file, remote_path] try: subprocess.run(command, check=True) print(f"文件已成功推送到 {remote_path}") except subprocess.CalledProcessError as e: print(f"推送文件失败: {e}") def enter_fastboot(): try: devices = subprocess.check_output(['adb', 'devices', '-l'], universal_newlines=True) for line in devices.splitlines(): if "usb" in line: pattern = r"usb:\S+" match = re.search(pattern, line) print(f'reboot bootloader:{match.group()}') subprocess.run(['adb', '-s', match.group(), 'shell', 'reboot', 'fastboot'], check=True) except subprocess.CalledProcessError as e: print(f"Error: {e}") def show_sdk_version(device_id): pass # device_info_dict,input_value,input_value_list, result = get_utp_port() # utp_version = '/sys/utp/version' # pb_hw_version = '/sys/ymtc_power_board/hw_version' # pb_sw_version = '/sys/ymtc_power_board/sw_version' # 构建adb命令 # adb_command1 = ['adb', '-s', device_id, 'shell', 'cat', utp_version] # subprocess.run(adb_command1) # adb_command2 = ['adb', '-s', device_id, 'shell', 'cat', pb_hw_version] # subprocess.run(adb_command2) # adb_command3 = ['adb', '-s', device_id, 'shell', 'cat', pb_sw_version] # subprocess.run(adb_command3) if __name__ == "__main__": logging.info(f'\033[1;31m=========00-执行升级前准备工作=========\033[0m') utp_zip_name = unzip_files(full_relative_path) logging.info(f"升级包的名字是:{utp_zip_name}") while utp_zip_name == None: utp_zip_name = unzip_files(full_relative_path) logging.info(f"没有解压的话,第二次获取,升级包的名字是:{utp_zip_name}") if check_files(full_relative_path) == 1: logging.info("\033[1;31m=========02-shell脚本数量是对的=========\033[0m") elif check_files(full_relative_path) == 2: copy_all_sh(bash_relative_path, full_relative_path) logging.info("=========copy file sucess!!=========") else: logging.info("升级的文件数量不对,请核查!!!") exit() # 选择操作(cp部分)之前,先获取目标IP列表 print("请选择目标主机指定方式:") print("1. 通过IP范围(输入起始和结束)") print("2. 通过预定义的IP列表") input_method = int(input("请输入选择(1或2): ")) if input_method == 1: # 范围输入方式 base_ip = input("请输入IP地址的前三段(例如 '10.26.92'): ") start = int(input("输入ip第四段的开始字段(例如10.26.92.228的228): ")) end = int(input("输入ip第四段的结束字段: ")) if start <= end: ip_list = [f"{base_ip}.{i}" for i in range(start, end + 1)] logging.info(f"通过范围生成IP列表: {ip_list}") else: logging.error("起始值必须小于或等于结束值") exit(1) elif input_method == 2: # 预定义列表方式 print("\n可用预定义IP列表:") for name in PREDEFINED_IP_LISTS: print(f" - {name}: {PREDEFINED_IP_LISTS[name]}") selected_lists = input("请输入要使用的列表名(多个用逗号分隔,例如 'list1,list2'): ").split(',') selected_lists = [name.strip() for name in selected_lists] ip_list = [] for name in selected_lists: if name in PREDEFINED_IP_LISTS: ip_list.extend(PREDEFINED_IP_LISTS[name]) else: logging.warning(f"未找到预定义列表 '{name}',已跳过") if not ip_list: logging.error("未选择任何有效的IP列表") exit(1) logging.info(f"使用预定义IP列表: {ip_list}") else: logging.error("无效的选择") exit(1) cp = int(input("\t\t\t\t选择你的操作 \n \ \t[1-【固件版本查看】((包括单)ip批量检查-默认10台port同时执行)] \n\ \t[2-【本地-固件版本查看】(只支持单ip操作-自行选择port进行查看)] \n \ \t[3-【本地-固件升级】(只支持单ip操作-自行选择port进行升级)] \n \ \t[4-【固件升级】((包括单)ip批量升级-默认10台port同时执行)] \n \ \t[5-杀掉.py后缀进程] [6-reboot fastboot下设备] [7-Into fastboot]\n \ \t[8-【sn修改】 \n \ \t[9-【Check ADB Version】 \n \ \t[10-【Update ADB Version】 \n \ \t[11-【offline设备的检测与恢复】] \n \ \t[12-【Tester Reboot】] \n \ \t[0-退出] 请输入:")) if cp == 0: exit() elif cp == 5: process_list = subprocess.run(['ps', '-ef'], stdout=subprocess.PIPE).stdout.decode() process_ids = [line.split()[1] for line in process_list.splitlines() if '.py' in line and 'grep' not in line] # kill all for pid in process_ids: subprocess.run(['kill', '-9', pid]) exit() elif cp == 6: try: devices_output = subprocess.check_output(['fastboot', 'devices', '-l'], universal_newlines=True) for device_line in devices_output.strip().split('\n'): device_serial = device_line.split(' ')[0] print(f"Rebooting device: {device_serial}") subprocess.run(['fastboot', '-s', device_serial, 'reboot'], check=True) except subprocess.CalledProcessError as e: print(f"Error: {e}") exit() elif cp == 7: enter_fastboot() exit() elif cp == 8: device_info_dict,input_value,input_value_list, result = get_utp_port() sn_num = input("你想要把port号改成多少? [1-999,输入1000退出] 请输入:") sn_num = f"{sn_num:0>3}" print(f"su_num:{sn_num}") if sn_num == 1000: exit() push_file_to_device(sn_relative_path, utp_data_tester_path, result) input_string = '0123456789N1Y' + str(sn_num) process = subprocess.Popen(['adb', '-s', result,'shell', 'sh', utp_sh_file],stdin=subprocess.PIPE) process.communicate(input_string.encode('utf-8')) time.sleep(1) result = subprocess.run(['adb', '-s', result, 'reboot'], capture_output=True, text=True) time.sleep(1) exit() elif cp == 11: print("\n" + "="*60) print("开始离线设备检测与恢复...") print("="*60) # 重置全局报告 offline_recovery_report = [] execute_tasks_with_thread_limit( ip_list, connect_with_ssh, USERNAME, # 使用全局用户名 PASSWORD, # 使用全局密码 cp, max_threads=10 ) # 生成最终报告 #print("\n" + "="*60) #print("离线设备检测与恢复汇总报告:") #print("="*60) success_count = 0 failure_count = 0 offline_devices = [] # 按IP分组显示结果 for ip in ip_list: ip_results = [r for r in offline_recovery_report if r["ip"] == ip] if not ip_results: print(f"\n❌ {ip}: 未获取到检测结果") continue #print(f"\nIP: {ip}") for result in ip_results: #status_icon = "✅" if "成功" in result["status"] or "在线" in result["status"] else "❌" #print(f" {status_icon} Device: {result['device']} | 状态: {result['status']}") if "成功" in result["status"] or "在线" in result["status"]: success_count += 1 else: failure_count += 1 if "失败" in result["status"]: offline_devices.append({ "ip": ip, "device": result["device"] }) # 输出仍然离线的设备 if offline_devices: print("\n" + "="*60) print("仍然离线的设备列表:") print("="*60) for device in offline_devices: print(f"❌ IP: {device['ip']} | Device: {device['device']}") # 输出统计摘要 print("\n" + "="*60) print("统计摘要:") print("="*60) print(f"✅ 成功恢复/在线设备: {success_count}个") print(f"❌ 恢复失败设备: {failure_count}个") print(f"🌐 扫描主机总数: {len(ip_list)}台") print(f"📊 检测设备总数: {success_count + failure_count}个") exit() elif cp == 12: # 处理Tester Reboot logging.info("\033[1;31m=========03进行远程ssh中,connecting...=========\033[0m") execute_tasks_with_thread_limit( ip_list, connect_with_ssh, USERNAME, PASSWORD, cp, max_threads=10 ) exit() # 对于选项1-4,9-10,使用已生成的ip_list logging.info("\033[1;31m=========03进行远程ssh中,connecting...=========\033[0m") threads = [] adb_check_failed_ips = [] adb_check_success_ips_9_10 = [] adb_check_failed_ips_9_10 = [] execute_tasks_with_thread_limit( ip_list, connect_with_ssh, USERNAME, PASSWORD, cp, max_threads=10 # 限制最大线程数为10 ) # 对于选项9/10,生成报告 if cp in [9, 10]: if cp == 9: report_title = "ADB版本检查结果汇总" success_label = "版本正确" failure_label = "版本错误或未安装" else: report_title = "ADB升级结果汇总" success_label = "升级成功" failure_label = "升级失败" print(f"\n===== {report_title} =====") success_count = len(adb_check_success_ips_9_10) failure_count = len(adb_check_failed_ips_9_10) total_count = len(ip_list) print(f"总计设备: {total_count}台") print(f"✅ {success_label}: {success_count}台") print(f"❌ {failure_label}: {failure_count}台") if failure_count > 0: print("\n失败设备列表:") for ip in adb_check_failed_ips_9_10: print(f" - {ip}") # 在执行完成后打印因ADB版本问题导致升级失败的IP if adb_check_failed_ips: print("\n" + "="*60) print("以下IP因ADB版本问题导致UTP升级失败:") for ip in sorted(set(adb_check_failed_ips)): print(f" - {ip}") print("="*60) #del_all_sh(full_relative_path) 现在有问题吗
12-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值