如何用Python subprocess结合ADB正确拉取APK?菜单选择报错排查
问题:选择APK序号后报错无法获取路径
我通过选择菜单序号来获取APK,打算后续用apktool反编译,但输入序号后出现报错:
/system/bin/sh:
[1]: 15: inaccessible or not found
无法获取APK路径,以下是我编写的代码,想找出问题所在:
# 创建模拟器上所有第三方应用的选择菜单,让用户选择一个 output = subprocess.run(["adb", "-s", device_id, "shell", "pm", "list", "packages", "-3"], capture_output=True).stdout.decode("utf-8") packages = output.strip().split("\n") print("Available packages:") for i, package in enumerate(packages): print(f"{i+1}: {package}") package_index = int(input("Enter the number of the package to extract: ")) - 1 print(package_index) # 打印选中包的路径并提取到本地 package = packages[package_index] print(package) ##print(packages) package_name = package.split(":")[1] print(package_name) new_output = subprocess.run(["adb","-s", device_id, "shell", "pm", "path", package_name], capture_output=True).stdout.decode("utf-8") package_path = new_output.strip().split(":")[1] #print(output) #print(package_path) #print(f"Full path of {package_name}: {package_path}") apk_type = input("Enter 1 to extract a single APK file, or 2 to extract a split APK: ") if apk_type == "1": print("Hhhhh") #subprocess.run(["adb" ,"-s", device_id, "pull", package_path, f"{package_name}.apk"]) else: print("Working in progress......................................")
问题排查与解决方法
1. 过滤空包项,避免无效索引
执行pm list packages -3后,输出可能包含空行,导致packages列表里有空字符串。当用户选中对应序号时,package.split(":")[1]会直接报错,因为空字符串没有: 分割项。
修改包列表生成代码,过滤空元素:
packages = [p for p in output.strip().split("\n") if p.strip()]
2. 校验pm path返回结果
如果pm path package_name返回的不是package:开头的有效路径(比如返回权限错误或包不存在的提示),new_output.strip().split(":")[1]会出现索引越界,或者拿到无效路径,进而导致后续操作报错。
添加结果校验逻辑:
new_output = subprocess.run( ["adb","-s", device_id, "shell", "pm", "path", package_name], capture_output=True, text=True ).stdout # 检查是否返回有效路径 if not new_output.strip().startswith("package:"): print(f"获取{package_name}路径失败,错误信息:{new_output.strip()}") exit(1) package_path = new_output.strip().split(":")[1]
3. 处理含特殊字符的路径
部分APK路径可能包含空格或特殊字符,直接传给adb pull会被shell拆分,导致找不到文件。可以用shlex.quote处理路径:
import shlex if apk_type == "1": print("正在提取APK...") subprocess.run([ "adb" ,"-s", device_id, "pull", shlex.quote(package_path), f"{package_name}.apk" ])
4. 解决权限访问问题
有些第三方应用的APK存放在受保护目录,普通adb pull无法访问。可以尝试用run-as命令导出:
# 先将APK复制到SD卡 subprocess.run([ "adb", "-s", device_id, "shell", f"run-as {package_name} cat {package_path} > /sdcard/{package_name}.apk" ]) # 再从SD卡拉到本地 subprocess.run([ "adb", "-s", device_id, "pull", f"/sdcard/{package_name}.apk", f"{package_name}.apk" ]) # 删除SD卡上的临时文件 subprocess.run([ "adb", "-s", device_id, "shell", f"rm /sdcard/{package_name}.apk" ])
内容的提问来源于stack exchange,提问作者Justice Chukwuemeka
相关产品推荐
相关产品推荐

