菜鸟科技网

Python如何执行ADB shell命令?

Python 通过 ADB shell 命令实现与 Android 设备的交互,是自动化测试、设备管理、数据获取等场景的核心技术,ADB(Android Debug Bridge)作为 Android 开发调试的桥梁,其 shell 命令可直接在设备或模拟器上执行系统级操作,而 Python 通过 subprocessos 或第三方库(如 pure-python-adbppadb)调用 ADB 命令,能高效整合自动化逻辑,以下从基础操作、进阶应用、代码实现及注意事项等方面展开详细说明。

Python如何执行ADB shell命令?-图1
(图片来源网络,侵删)

Python 调用 ADB shell 命令的基础方法

Python 执行 ADB 命令的核心是通过 subprocess 模块启动子进程,将 ADB 命令作为系统命令传递,常见方法包括 subprocess.run()subprocess.Popen()os.system()subprocess.run() 因其简洁性和参数控制能力成为主流。

基本语法

import subprocess
# 执行简单 ADB 命令,获取输出结果
result = subprocess.run(["adb", "shell", "ls /sdcard"], 
                        capture_output=True, text=True, check=True)
print(result.stdout)  # 输出命令执行结果
  • capture_output=True:捕获标准输出和错误输出。
  • text=True:以文本形式返回输出(默认为字节)。
  • check=True:若命令执行失败(非零退出码)则抛出 subprocess.CalledProcessError

带参数的动态命令

当命令需动态拼接参数时(如指定设备、传递文件路径),需注意参数列表的规范性:

device_id = "emulator-5554"
path = "/sdcard/test.txt"
command = ["adb", "-s", device_id, "shell", "cat", path]
result = subprocess.run(command, capture_output=True, text=True)
print(result.stdout)

常见 ADB shell 命令与 Python 实现场景

ADB shell 命令涵盖文件操作、系统信息、应用管理、设备控制等多个维度,以下结合 Python 实现典型用例。

文件与目录操作

通过 adb shell 可对设备文件系统进行读写,Python 用于封装逻辑并处理结果。

Python如何执行ADB shell命令?-图2
(图片来源网络,侵删)
命令功能 ADB shell 命令示例 Python 实现思路
列出目录内容 adb shell ls /sdcard 调用命令后解析 stdout,按行分割文件列表
创建目录 adb shell mkdir /sdcard/new_dir 使用 subprocess.run() 执行,检查 returncode 确认是否成功
复制文件 adb shell cp /sdcard/a.txt /sdcard/b.txt 封装为函数,返回操作结果(成功/失败)
删除文件 adb shell rm /sdcard/test.txt 结合 try-except 捕获错误输出(如权限不足、文件不存在)

示例:列出并过滤 SD 卡图片文件

def get_sdcard_images():
    command = ["adb", "shell", "ls /sdcard/Pictures"]
    result = subprocess.run(command, capture_output=True, text=True)
    if result.returncode == 0:
        images = [line.strip() for line in result.stdout.split('\n') if line.endswith(('.jpg', '.png'))]
        return images
    else:
        print(f"Error: {result.stderr}")
        return []
images = get_sdcard_images()
print("SD卡图片列表:", images)

系统信息获取

自动化测试中常需获取设备型号、Android 版本、内存等信息,Python 可用于结构化处理数据。

信息类型 ADB shell 命令示例 Python 处理方式
设备型号 adb shell getprop ro.product.model 提取 stdout 并去除首尾空白字符
Android 版本 adb shell getprop ro.build.version.release 同上,可存储为变量用于脚本逻辑分支
内存使用情况 adb shell cat /proc/meminfo 解析输出中的 MemTotalMemFree,计算内存占用率
CPU 信息 adb shell cat /proc/cpuinfo 提取 HardwareProcessor 等字段,返回字典格式

示例:获取设备基本信息并格式化输出

def get_device_info():
    info = {}
    commands = {
        "model": ["adb", "shell", "getprop", "ro.product.model"],
        "android_version": ["adb", "shell", "getprop", "ro.build.version.release"],
        "serial": ["adb", "shell", "getprop", "ro.serialno"]
    }
    for key, cmd in commands.items():
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            info[key] = result.stdout.strip()
    return info
device_info = get_device_info()
print(f"设备型号: {device_info['model']}, Android版本: {device_info['android_version']}")

应用管理

自动化测试需控制应用的启动、停止、卸载等操作,Python 可结合 ADB 命令实现流程控制。

Python如何执行ADB shell命令?-图3
(图片来源网络,侵删)
操作类型 ADB shell 命令示例 Python 应用场景
启动应用 adb shell am start -n com.example/.MainActivity 测试用例初始化时启动被测应用
停止应用 adb shell am force-stop com.example 测试结束后清理应用进程,避免残留
卸载应用 adb shell pm uninstall com.example CI/CD 流程中自动卸载旧版本应用
检查应用是否安装 adb shell pm list packages | grep com.example 通过 grep 过滤输出,返回 True/False 判断安装状态

示例:判断应用是否安装并卸载

def is_app_installed(package_name):
    command = ["adb", "shell", "pm", "list", "packages", "|", "grep", package_name]
    result = subprocess.run(command, shell=True, capture_output=True, text=True)  # 注意:shell=True 用于管道符
    return package_name in result.stdout
def uninstall_app(package_name):
    if is_app_installed(package_name):
        command = ["adb", "shell", "pm", "uninstall", package_name]
        result = subprocess.run(command, capture_output=True, text=True)
        if result.returncode == 0:
            print(f"应用 {package_name} 卸载成功")
        else:
            print(f"卸载失败: {result.stderr}")
    else:
        print(f"应用 {package_name} 未安装")
uninstall_app("com.example.test")

设备控制与模拟操作

通过 ADB shell 可模拟点击、滑动、输入等操作,结合 Python 实现自动化交互。

操作类型 ADB shell 命令示例 Python 实现要点
模拟点击 adb shell input tap 500 300 将坐标作为参数传递,封装为点击函数
模拟滑动 adb shell input swipe 100 500 500 500 300 起始坐标、结束坐标、滑动时长(毫秒)作为参数
输入文本 adb shell input text "Hello" 需对特殊字符转义(如空格用 \\),或通过 shell 参数传递
截图 adb shell screencap -p /sdcard/screen.png 截图后通过 adb pull 传输到本地,结合 PIL 进行图像处理

示例:模拟解锁滑动(示例坐标)

def swipe_unlock(start_x, start_y, end_x, end_y, duration=300):
    command = ["adb", "shell", "input", "swipe", str(start_x), str(start_y), str(end_x), str(end_y), str(duration)]
    subprocess.run(command, check=True)
# 模拟从左向右滑动解锁
swipe_unlock(100, 500, 500, 500, 500)

进阶应用与注意事项

多设备管理

当连接多台设备时,需通过 -s 参数指定设备 ID,Python 可动态获取设备列表并分配任务:

def get_connected_devices():
    command = ["adb", "devices"]
    result = subprocess.run(command, capture_output=True, text=True)
    devices = []
    for line in result.stdout.split('\n')[1:]:  # 跳过第一行 "List of devices attached"
        if line.strip():
            devices.append(line.split('\t')[0])
    return devices
devices = get_connected_devices()
if devices:
    print(f"当前设备列表: {devices}")
    # 示例:对第一台设备执行操作
    subprocess.run(["adb", "-s", devices[0], "shell", "input", "keyevent", "HOME"])
else:
    print("未检测到设备")

异常处理与日志

ADB 命令可能因设备未授权、命令错误等失败,需通过 try-except 捕获异常并记录日志:

import logging
logging.basicConfig(filename='adb_operations.log', level=logging.ERROR)
def safe_adb_command(command):
    try:
        result = subprocess.run(command, capture_output=True, text=True, check=True)
        return result.stdout
    except subprocess.CalledProcessError as e:
        logging.error(f"命令执行失败: {' '.join(command)}, 错误: {e.stderr}")
        return None
output = safe_adb_command(["adb", "shell", "invalid_command"])
if output is None:
    print("命令执行出错,请查看日志")

性能优化

  • 避免频繁创建子进程:对多次执行的命令(如 adb shell),可保持 ADB 守护进程运行,通过 adb shell - 进入交互模式。
  • 并发执行:使用 concurrent.futures 并行操作多设备,提升效率。

相关问答FAQs

Q1: Python 调用 ADB 命令时提示“adb: command not found”,如何解决?
A: 该错误通常表示系统中未安装 ADB 或环境变量未配置,解决步骤如下:

  1. 下载 ADB 工具(Android SDK Platform Tools),并将其 platform-tools 目录路径添加到系统环境变量 PATH 中。
  2. 验证安装:在终端执行 adb version,若显示版本信息则配置成功。
  3. 若 Python 脚本中需指定 ADB 路径(如非标准安装),可通过 subprocess.run(["/path/to/adb", "shell", ...]) 指定完整路径。

Q2: 如何通过 Python 获取 ADB 命令的错误输出并调试?
A: 使用 subprocess.run() 时,可通过 capture_output=True 捕获标准错误(stderr),结合 try-except 处理异常。

try:
    result = subprocess.run(["adb", "shell", "rm /system/allowed"], check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
    print(f"命令执行失败,错误码: {e.returncode}")
    print(f"错误输出: {e.stderr}")  # 通常包含具体错误原因,如 "Permission denied"

可通过 adb logcat 查看设备日志,或启用 subprocessuniversal_newlines=True(等同于 text=True)确保输出编码正确。

分享:
扫描分享到社交APP
上一篇
下一篇