ADB命令自动化进阶:用.bat脚本实现多设备循环操作与日志抓取
企业级安卓设备批量运维用批处理脚本构建自动化测试与日志管理流水线如果你负责管理一个由数十台甚至上百台安卓设备组成的测试实验室每天重复着连接设备、执行测试、收集日志的繁琐工作那么这篇文章正是为你准备的。在移动应用质量保障和硬件测试领域手动操作多台设备不仅效率低下而且极易出错。一次简单的压力测试可能需要工程师在多个终端窗口间不停切换复制粘贴命令稍有不慎就会漏掉某台设备的关键日志。这种场景下自动化脚本不再是“锦上添花”的优化而是保障测试一致性、提升团队产能的“雪中送炭”。今天我们将深入探讨如何利用 Windows 批处理脚本.bat构建一套面向多安卓设备的自动化操作框架。这套方案的核心价值在于它将零散的adb命令编织成一条高效的流水线自动发现所有在线设备为每台设备创建独立的沙盒环境并行或串行执行定制化测试指令并将海量日志分门别类地归档存储。更重要的是我们将融入企业级应用所需的容错机制比如设备离线自动重连、命令执行超时处理、异常状态捕获等让整个流程在无人值守的情况下也能稳定运行。1. 环境准备与基础命令封装在开始编写复杂的批处理脚本之前我们需要确保基础环境稳固并将一些常用的、容易出错的adb操作封装成可靠的功能模块。这就像盖房子前先打好地基、准备好标准化的预制件。1.1 确保ADB环境就绪首先adbAndroid Debug Bridge必须能在系统的任何路径下被调用。最稳妥的方式不是依赖用户配置的环境变量而是在脚本开头主动定位adb。echo off setlocal enabledelayedexpansion REM 尝试多种方式定位adb.exe set ADB_PATH if exist %ANDROID_HOME%\platform-tools\adb.exe ( set ADB_PATH%ANDROID_HOME%\platform-tools\adb.exe ) else if exist adb.exe ( set ADB_PATHadb.exe ) else ( echo [错误] 未找到 adb.exe。请确保 echo 1. 已将 adb 所在目录如 D:\Android\Sdk\platform-tools添加到系统 PATH 环境变量或 echo 2. 将本脚本与 adb.exe 放置在同一目录下。 pause exit /b 1 ) echo [信息] 使用ADB路径: %ADB_PATH%注意上述脚本片段展示了防御性编程的思路。它首先检查ANDROID_HOME这个常见的环境变量然后检查当前目录如果都找不到则给出明确的指引并退出避免后续命令全部失败。1.2 封装核心ADB操作函数在批处理中我们可以利用call标签来模拟函数将重复使用的逻辑模块化。REM 函数执行ADB命令并检查结果 :ExecuteAdb setlocal set cmd%* echo [执行] %ADB_PATH% %cmd% %ADB_PATH% %cmd% if !errorlevel! neq 0 ( echo [警告] 命令执行失败错误码: !errorlevel! endlocal set GLOBAL_ERROR1 ) else ( endlocal set GLOBAL_ERROR0 ) exit /b REM 函数获取设备序列号列表 :GetDeviceList setlocal enabledelayedexpansion set DEVICE_LIST set COUNTER0 for /f tokens1 %%i in (%ADB_PATH% devices ^| findstr /r ^[0-9a-fA-F]) do ( set /a COUNTER1 set device_!COUNTER!%%i if !DEVICE_LIST! (set DEVICE_LIST%%i) else (set DEVICE_LIST!DEVICE_LIST!,%%i) ) endlocal set DEVICE_COUNT%COUNTER% set DEVICE_LIST%DEVICE_LIST% exit /b这里:GetDeviceList函数是关键。它使用adb devices列出设备并通过findstr过滤掉头信息和离线设备只保留在线设备的序列号存入变量供后续使用。%ADB_PATH% devices ^| findstr /r ^[0-9a-fA-F]这个命令组合中^|是对管道符|的转义findstr的正则表达式^[0-9a-fA-F]用于匹配以十六进制数字开头的行即设备序列号。2. 构建多设备发现与初始化框架有了基础函数我们就可以构建脚本的主干逻辑了。第一步是动态发现当前连接的所有设备并为每台设备做好测试准备。2.1 动态设备发现与信息收集一个健壮的脚本应该能处理设备数量从0到N的各种情况。call :GetDeviceList if %DEVICE_COUNT% equ 0 ( echo [错误] 未检测到任何已连接的Android设备。 echo 请检查 echo 1. USB线是否连接稳定或无线调试adb connect是否成功。 echo 2. 设备上是否已开启“开发者选项”和“USB调试”。 echo 3. 对于首次连接的电脑设备上可能弹出“允许USB调试吗”的提示请点击“确定”。 pause exit /b 1 ) echo [信息] 共发现 %DEVICE_COUNT% 台设备%DEVICE_LIST% echo. REM 遍历每台设备获取详细信息 for /l %%d in (1, 1, %DEVICE_COUNT%) do ( call :GetDeviceInfo %%d )接下来我们实现:GetDeviceInfo函数它调用adb -s 设备序列号 shell getprop来获取设备型号、Android版本等关键信息并创建以设备型号和序列号后四位命名的专属目录。:GetDeviceInfo setlocal set idx%1 call set device_serial%%device_%idx%%% REM 获取设备型号用于创建目录名 for /f tokens2 delims: %%m in (%ADB_PATH% -s %device_serial% shell getprop ro.product.model) do set model%%m REM 清理型号中的非法文件名字符如空格、冒号 set model!model:/_! set model!model: _! set model!model::_! REM 取序列号后四位作为唯一标识 set short_id!device_serial:~-4! REM 创建本次运行的日志根目录格式Logs_YYYYMMDD_HHMMSS set timestamp%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2% set timestamp!timestamp: 0! REM 处理时间中可能存在的空格 set LOG_ROOTLogs_!timestamp! if not exist !LOG_ROOT! mkdir !LOG_ROOT! REM 为当前设备创建专属子目录格式型号_短序列号 set DEVICE_DIR!LOG_ROOT!\!model!_!short_id! mkdir !DEVICE_DIR! 2nul echo [信息] 设备 !device_serial! (!model!) 的日志将保存至!DEVICE_DIR! REM 保存设备信息到文件 echo 设备序列号: !device_serial! !DEVICE_DIR!\device_info.txt echo 设备型号: !model! !DEVICE_DIR!\device_info.txt %ADB_PATH% -s !device_serial! shell getprop ro.build.version.release !DEVICE_DIR!\device_info.txt endlocal set device_dir_%idx%!DEVICE_DIR! exit /b这个函数做了几件重要的事1) 获取设备型号并净化成合法的文件夹名2) 生成一个包含时间戳的总日志目录避免多次运行覆盖旧日志3) 为每台设备创建独立的子目录4) 将设备基本信息写入文件便于后续追溯。3. 实现并行测试执行与日志捕获这是脚本的核心环节。我们将演示两种模式顺序执行适合对设备有状态依赖的操作和模拟并行利用批处理的start命令为新设备开新窗口适合独立测试。3.1 顺序执行模式与实时日志对于需要严格按顺序执行或者命令间有依赖关系的测试我们使用循环逐台设备执行。echo [阶段] 开始顺序执行压力测试... for /l %%d in (1, 1, %DEVICE_COUNT%) do ( call set device_serial%%device_%%d%% call set device_dir%%device_dir_%%d%% echo. echo 正在处理设备: !device_serial! REM 示例执行一个模拟CPU压力的命令并实时输出日志 echo [%time%] 开始CPU压力测试... !device_dir!\test_log.txt REM 这里使用一个简单的循环命令作为压力测试示例 REM 实际项目中可能是启动Monkey测试、运行特定APK或shell脚本 %ADB_PATH% -s !device_serial! shell for i in \$(seq 1 5); do echo 压力测试轮次 \$i; cat /proc/stat | head -1; sleep 2; done !device_dir!\cpu_stress.log 21 REM 捕获logcat日志带时间戳和进程过滤到独立文件 echo [%time%] 开始捕获应用日志... !device_dir!\test_log.txt start Logcat_!short_id! /B cmd /c %ADB_PATH% -s !device_serial! logcat -v time -s MyAppTag *:E !device_dir!\app_error.log REM 主测试命令这里替换成你的实际测试命令例如启动一个自动化测试APK call :ExecuteAdb -s !device_serial! shell am start -n com.example.test/.MainActivity timeout /t 10 /nobreak nul REM 等待10秒模拟测试过程 REM 测试结束停止后台的logcat捕获进程 taskkill /FI WINDOWTITLE eq Logcat_!short_id! /F nul 21 echo [%time%] 设备 !device_serial! 测试完成。 !device_dir!\test_log.txt )在上面的循环中我们为每台设备做了几件事1) 执行一个模拟的CPU压力测试命令并将输出重定向到设备专属目录下的cpu_stress.log2) 使用start命令在后台启动一个独立的cmd窗口来持续抓取logcat日志过滤了特定标签和错误级别并将其输出重定向到文件3) 执行核心测试命令示例中是启动一个Activity4) 测试完成后通过taskkill根据窗口标题关闭对应的logcat抓取进程。3.2 模拟并行执行模式当各设备测试任务完全独立时我们可以让它们同时开始以节省总耗时。批处理本身不支持真正的多线程但可以用start命令启动多个独立进程。echo [阶段] 开始并行执行兼容性测试... for /l %%d in (1, 1, %DEVICE_COUNT%) do ( call set device_serial%%device_%%d%% call set device_dir%%device_dir_%%d%% REM 为每台设备启动一个新的命令行窗口执行测试脚本 start Device_!device_serial! cmd /c call :RunDeviceTest !device_serial! !device_dir! ) REM 等待所有并行任务完成 echo [信息] 所有设备测试任务已启动正在并行执行中... echo 请勿关闭本窗口它将等待所有任务完成后进行汇总。 pause goto :WaitForCompletion这里start Device_!device_serial! cmd /c ...会为每台设备打开一个新的命令提示符窗口标题包含序列号并在其中调用一个名为:RunDeviceTest的“函数”实际上是另一个标签段落传入设备序列号和日志目录参数。然后主脚本会暂停等待用户确认所有任务都已下发。我们需要在脚本后面定义这个“函数”:RunDeviceTest setlocal set device_serial%~1 set device_dir%~2 echo [设备 %device_serial%] 并行测试开始于 %time% %device_dir%\parallel_log.txt REM 这里是针对单台设备的完整测试序列 call :ExecuteAdb -s %device_serial% shell input keyevent 26 REM 模拟按下电源键 timeout /t 2 /nobreak nul call :ExecuteAdb -s %device_serial% shell input swipe 500 1500 500 500 REM 模拟滑动解锁 REM ... 更多测试命令 echo [设备 %device_serial%] 并行测试结束于 %time% %device_dir%\parallel_log.txt REM 创建一个标记文件通知主进程本设备测试完成 echo done %device_dir%\FINISHED.txt exit /b并行执行的关键在于进程间通信。这里我们采用了一个简单有效的方案每台设备的子进程在完成任务后在自己的日志目录中创建一个特定的标记文件如FINISHED.txt。主进程可以通过检查所有设备目录中是否都存在这个标记文件来判断所有任务是否完成。:WaitForCompletion :WaitLoop set ALL_FINISHED1 for /l %%d in (1, 1, %DEVICE_COUNT%) do ( call set device_dir%%device_dir_%%d%% if not exist !device_dir!\FINISHED.txt set ALL_FINISHED0 ) if !ALL_FINISHED! equ 0 ( echo 等待设备测试完成... 已等待 %WAIT_SECONDS% 秒 set /a WAIT_SECONDS5 timeout /t 5 /nobreak nul goto WaitLoop ) echo [信息] 所有设备并行测试已完成4. 设计容错机制与日志归档策略任何用于生产环境的自动化脚本都必须考虑异常处理。设备可能意外断开命令可能执行超时磁盘可能空间不足。4.1 设备连接状态监控与重连我们可以在关键命令执行前插入一个连接检查步骤。REM 函数检查设备是否在线如果离线则尝试重连 :CheckDeviceConnection setlocal set device_serial%~1 set max_retries3 set retry_count0 :CheckLoop %ADB_PATH% devices | findstr /c:%device_serial% | findstr /c:device nul if !errorlevel! equ 0 ( echo [设备 %device_serial%] 连接正常。 endlocal set CONNECTION_STATUSOK exit /b 0 ) else ( set /a retry_count1 if !retry_count! gtr !max_retries! ( echo [错误] 设备 %device_serial% 离线重连 %max_retries% 次后失败。 endlocal set CONNECTION_STATUSFAIL exit /b 1 ) echo [警告] 设备 %device_serial% 离线尝试重连 (!retry_count!/!max_retries!)... REM 尝试TCP/IP重连假设之前已通过adb connect连接过 %ADB_PATH% connect %device_serial% nul 21 timeout /t 2 /nobreak nul goto CheckLoop )在测试循环中可以这样调用call :CheckDeviceConnection !device_serial! if !CONNECTION_STATUS!FAIL ( echo [跳过] 设备 !device_serial! 无法连接跳过此设备测试。 echo OFFLINE !device_dir!\status.txt continue )4.2 命令执行超时控制有些adb shell命令可能挂起。我们可以利用timeout命令和任务管理来强制结束长时间运行的任务。REM 函数带超时执行的ADB命令 :ExecuteAdbWithTimeout setlocal set device_serial%~1 set timeout_sec%~2 set command%~3 REM 启动一个后台进程执行命令并将其输出重定向到临时文件 set temp_output%temp%\adb_output_%random%.txt start AdbCmd_%device_serial% /B cmd /c %ADB_PATH% -s %device_serial% %command% %temp_output% 21 set cmd_pid!errorlevel! REM 等待指定时间 timeout /t %timeout_sec% /nobreak nul REM 检查进程是否仍在运行 tasklist /fi pid eq %cmd_pid% /fo csv 2nul | findstr /i cmd.exe nul if !errorlevel! equ 0 ( echo [超时] 命令执行超过 %timeout_sec% 秒强制终止。 taskkill /pid %cmd_pid% /f nul 21 echo [命令超时强制结束] %temp_output% endlocal set CMD_TIMEOUT1 ) else ( endlocal set CMD_TIMEOUT0 ) REM 读取并输出临时文件内容然后删除 type %temp_output% del %temp_output% 2nul exit /b4.3 结构化日志归档与报告生成测试完成后我们需要将分散的日志整理成一份清晰的报告。以下脚本片段展示了如何汇总各设备的测试状态并打包日志。echo [阶段] 测试完成正在生成汇总报告... set REPORT_FILE%LOG_ROOT%\测试报告_%timestamp%.txt echo 批量设备测试报告 %REPORT_FILE% echo 生成时间: %date% %time% %REPORT_FILE% echo 设备总数: %DEVICE_COUNT% %REPORT_FILE% echo. %REPORT_FILE% set /a SUCCESS_COUNT0 set /a FAIL_COUNT0 for /l %%d in (1, 1, %DEVICE_COUNT%) do ( call set device_serial%%device_%%d%% call set device_dir%%device_dir_%%d%% if exist !device_dir!\status.txt ( set /a FAIL_COUNT1 set status失败 ) else ( set /a SUCCESS_COUNT1 set status成功 ) echo 设备序列号: !device_serial! %REPORT_FILE% echo 日志目录: !device_dir! %REPORT_FILE% echo 测试状态: !status! %REPORT_FILE% echo -------------------- %REPORT_FILE% ) echo. %REPORT_FILE% echo 汇总 %REPORT_FILE% echo 成功: %SUCCESS_COUNT% 台 %REPORT_FILE% echo 失败: %FAIL_COUNT% 台 %REPORT_FILE% REM 可选将整个日志目录压缩便于传输和存档 REM 需要系统中安装有压缩工具如7-Zip if exist C:\Program Files\7-Zip\7z.exe ( C:\Program Files\7-Zip\7z.exe a -tzip %LOG_ROOT%.zip %LOG_ROOT%\* nul echo [信息] 日志已压缩至: %LOG_ROOT%.zip ) echo. echo [完成] 所有操作执行完毕 echo 详细报告请查看: %REPORT_FILE% echo 原始日志位于: %LOG_ROOT% 目录最后为了让整个脚本更易用我们可以将所有这些模块组合起来并提供简单的菜单驱动界面。:MainMenu cls echo echo 安卓设备批量自动化测试控制台 echo echo 当前连接设备: %DEVICE_COUNT% 台 echo. echo 请选择操作 echo 1. 刷新设备列表 echo 2. 顺序执行标准压力测试 echo 3. 并行执行兼容性测试 echo 4. 仅抓取所有设备日志不执行测试 echo 5. 清理临时文件并退出 echo. set /p choice请输入选项1-5: if %choice%1 goto RefreshDevices if %choice%2 goto SequentialTest if %choice%3 goto ParallelTest if %choice%4 goto CollectLogsOnly if %choice%5 goto CleanupAndExit echo 无效选项请重新输入。 pause goto MainMenu将这样一个批处理脚本部署到测试团队的共享目录任何成员只需双击就能以一致、可靠的方式对实验室的所有设备发起测试。它消除了手动操作的不确定性将测试人员从重复劳动中解放出来让他们能更专注于分析测试结果和定位深层问题。这套框架可以根据实际需求轻松扩展例如集成到持续集成CI流水线中或者增加邮件通知功能在测试完成后自动发送报告。

相关新闻

J-Flash高级技巧:如何精准配置FLASH地址实现分区烧录(以STM32为例)

J-Flash高级技巧:如何精准配置FLASH地址实现分区烧录(以STM32为例)

J-Flash高级技巧:如何精准配置FLASH地址实现分区烧录(以STM32为例) 如果你已经用J-Flash做过几次简单的全片擦写和程序下载,可能会觉得它就是个“傻瓜式”工具,点几下鼠标就完事了。但当你面对一个复杂的项目&#xff…

2026/7/3 8:23:36 阅读更多 →
RAG-04响应与生成模块

RAG-04响应与生成模块

RAG之响应与生成模块 概述 检索增强生成(RAG)的响应生成模块是将检索到的相关信息与大型语言模型(LLM)结合,生成高质量、准确且上下文相关的响应的关键组件。本指南详细介绍了如何有效利用检索到的信息来增强LLM的输出,包括各种响应生成策略和实用的Prom…

2026/5/17 12:33:40 阅读更多 →
RAG-03查询与检索模块

RAG-03查询与检索模块

RAG之查询与检索模块 概述 检索增强生成(Retrieval-Augmented Generation, RAG)系统的核心在于其查询与检索模块,该模块负责准确高效地从知识库中检索出相关信息,为后续的生成任务提供上下文支持。本文档将详细介绍RAG系统中的查询变换、排序与后处理、混…

2026/7/4 6:54:23 阅读更多 →

最新新闻

3步解决Navicat试用限制:macOS数据库开发者的终极方案

3步解决Navicat试用限制:macOS数据库开发者的终极方案

3步解决Navicat试用限制:macOS数据库开发者的终极方案 【免费下载链接】navicat_reset_mac navicat mac版无限重置试用期脚本 Navicat Mac Version Unlimited Trial Reset Script 项目地址: https://gitcode.com/gh_mirrors/na/navicat_reset_mac 你是否也曾…

2026/7/4 19:33:32 阅读更多 →
蓝凌EIS平台SQL注入漏洞(CVE-2025-22214)深度剖析与实战复现

蓝凌EIS平台SQL注入漏洞(CVE-2025-22214)深度剖析与实战复现

1. 项目概述:一次针对企业协同平台的SQL注入漏洞深度剖析最近在安全圈里,蓝凌EIS智慧协同平台的一个SQL注入漏洞(CVE-2025-22214)引起了我的注意。这个漏洞出在fi_message_receiver.aspx这个接口上,攻击者甚至不需要登…

2026/7/4 19:33:32 阅读更多 →
使用DALL·E 3和Python自动生成AI配图PPT

使用DALL·E 3和Python自动生成AI配图PPT

1. 为什么需要自动生成带AI配图的PPT?在商业汇报、学术展示和日常工作中,PPT制作往往占据大量时间。传统流程需要经历内容整理、版式设计、图片搜索/制作等多个环节,尤其配图部分最耗时——要么花费数小时在免费图库中寻找合适素材&#xff0…

2026/7/4 19:31:32 阅读更多 →
面向钓鱼邮件研判的智能体 AI 流水线架构与工程实践研究

面向钓鱼邮件研判的智能体 AI 流水线架构与工程实践研究

摘要 全球钓鱼攻击总量持续高速增长,2025 年全年钓鱼攻击总量突破 380 万起,仅第二季度上报钓鱼邮件数量超 110 万封,海量可疑邮件上报给安全运营中心(SOC)带来巨大人工研判压力。传统单一大模型检测方案存在可解释性差…

2026/7/4 19:31:32 阅读更多 →
反潜航空深弹命中概率问题的数学建模与优化研究

反潜航空深弹命中概率问题的数学建模与优化研究

反潜航空深弹命中概率问题的数学建模与优化研究 副标题:基于随机过程理论与 Monte Carlo 模拟的航空深弹投弹策略最优设计 竞赛:2024年高教社杯全国大学生数学建模竞赛 D题 关键词:航空深弹 命中概率 截尾正态分布 Monte Carlo模拟 阵列优化 摘要:本文针对2024年全国大…

2026/7/4 19:31:32 阅读更多 →
PCB阻抗线设计与立创EDA专业版设置指南

PCB阻抗线设计与立创EDA专业版设置指南

1. 阻抗线基础概念与设计要点在PCB设计中,阻抗线是指具有特定特性阻抗的传输线,主要用于高频信号传输(如射频、高速数字信号)。阻抗匹配是确保信号完整性的关键因素,不匹配会导致信号反射、振铃和功率损耗。阻抗线的特…

2026/7/4 19:27:31 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻