自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
设备 shell 命令
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
在 VTS 测试期间,shell 命令用于执行目标端测试二进制文件,获取/设置属性、环境变量和系统信息以及启动/停止 Android 框架。您可以使用 adb shell
命令或设备上运行的 VTS shell 驱动程序(推荐采用此方式)执行 VTS 设备 shell 命令。
使用 adb shell
如果在测试期间需要关闭 USB 端口或重新启动设备,则必须使用 adb shell,因为如果没有持久的 USB 连接,VTS shell 驱动程序将不可用。您可以从 Python 测试脚本中的 AndroidDevice
对象调用 adb shell。示例:
- 获取 Android 设备对象:
self.device = self.android_devices[0]
- 发出一个 shell 命令:
result = self.device.adb.shell(‘ls')
使用 VTS shell 驱动程序
VTS shell 驱动程序是一个代理二进制文件,该文件会在设备上运行并执行 shell 命令。默认情况下,如果 shell 驱动程序在设备上运行,则 VTS 将使用该驱动程序,因为此方法比使用 adb
shell
命令的延迟更短。

图 1. VTS shell 驱动程序。
VTS 框架支持多设备测试,其中每部 Android 设备都在基础运行程序中显示为一个 AndroidDevice 对象。默认情况下,VTS 框架会将 VTS 代理和 VTS shell 驱动程序二进制文件推送到每部 Android 设备,并与这些设备上的 VTS 代理建立 TCP 连接。
要执行 shell 命令,主机端 Python 脚本会对 AndroidDevice 对象内的 ShellMirror 对象发出函数调用。ShellMirror 对象将 shell 命令文本打包成 protobuf 消息,并通过 TCP 通道将其发送至 Android 设备上的 VTS 代理。然后,设备上运行的代理通过 Unix 套接字将 shell 命令转发给 VTS shell 驱动程序。
当 VTS shell 驱动程序收到一个 shell 命令时,它会在设备 shell 上通过 nohup 执行该命令以防止中断。然后从 nohup
检索 stdout、stderr 和返回代码并将其发送回 VTS 代理。最后,代理通过将命令结果封装成 protobuf
消息来回复主机。
优点
使用 VTS shell 驱动程序(而不是 adb
shell
)的优点包括:
- 可靠性。VTS shell 驱动程序使用
nohup
执行命令(采用默认设置)。由于 VTS 测试主要是较低级别的 HAL 和内核测试,因此 nohup
可确保 shell 命令在执行期间不会中断。
- 性能。虽然
adb shell
命令会缓存一些结果(例如列出目录中的文件),但在执行任务(例如执行测试二进制文件)时,它会产生连接开销。VTS shell 驱动程序在整个测试过程中保持有效连接,所以唯一的开销是 USB 通信。在我们的测试中,使用 VTS shell 驱动程序执行一个具有 100 个空 Gtest 二进制文件调用的命令比使用 adb shell
快约 20%。由于 VTS shell 通信需要完成大量日志记录工作,因此实际差异更大。
- 状态保持。VTS shell 驱动程序为每个终端名称(默认终端名称为“default”)保持一个终端会话。在某个终端会话中设置的环境变量仅适用于同一会话中的后续命令。
- 可扩展性。VTS 框架和设备驱动程序之间的 shell 命令通信封装在 protobuf 中,以便日后能够进行压缩、远程控制、加密等。还存在其他提高性能的可能性,包括通信开销大于结果字符串解析时的设备端结果解析。
缺点
使用 VTS shell 驱动程序(而不是 adb
shell
)的缺点包括:
- 额外的二进制文件。VTS 代理文件必须推送到设备并在测试执行之后清理干净。
- 需要有效连接。如果主机和代理之间的 TCP 连接在测试期间有意或无意地断开(由于 USB 连接断开、端口关闭、设备崩溃等),shell 命令将无法传输到 VTS 代理。即使自动切换到
adb shell
,断开连接之前的命令结果和状态也是未知的。
示例
在 VTS 主机端 Python 测试脚本中使用 shell 命令的示例:
- 获取 Android 设备对象:
self.device = self.android_devices[0]
- 为所选设备获取 shell 对象:
self.shell = self.device.shell
- 发出一个 shell 命令:
results = self.shell.Execute(‘ls')
- 发出一串 shell 命令:
results = self.shell.Execute([‘cd /data/local/tmp', ‘ls'])
命令结果对象
执行 shell 命令后的返回对象是一个包含键 stdouts
、stderrs
和 return_codes
的字典。无论 shell 命令是作为单个字符串还是命令字符串列表提供,结果字典的每个值都始终是一个列表。
如需验证命令列表的返回代码,测试脚本必须检查索引。示例:
asserts.assertFalse(any(results[‘return_codes']), ‘some command failed.')
或者,脚本可以单独检查每个命令索引。示例:
asserts.assertEqual(results[‘return_codes'][0], 0, ‘first command failed')
asserts.assertEqual(results[‘return_codes'][1], 0, ‘second command failed')
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[null,null,["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Device shell commands\n\nDuring VTS testing, shell commands are used to execute a target-side test\nbinary, to get/set properties, environment variables, and system information,\nand to start/stop the Android framework. You can execute VTS device shell\ncommands using the `adb shell` command or the VTS shell driver\nrunning on the device (recommended).\n\nUse ADB shell\n-------------\n\nTests that require shutting down the USB port or rebooting the device during\ntesting must use ADB shell as the VTS shell driver is unavailable without a\npersistent USB connection. You can invoke ADB shell from the\n`AndroidDevice` object in the Python test script. Examples:\n\n- Get an Android device object: \n\n ```\n self.device = self.android_devices[0]\n ```\n- Issue a single shell command: \n\n ```\n result = self.device.adb.shell(‘ls')\n ```\n\nUse the VTS shell driver\n------------------------\n\nThe VTS shell driver is an agent binary that runs on the device and executes\nshell commands. By default, VTS uses the shell driver if the driver is running\non device because this method has less latency than using the `adb\nshell` command.\n\n**Figure 1.** VTS shell driver.\n\nThe VTS framework supports multi-device testing where each Android device\nis represented as an AndroidDevice object in base runner. By default, VTS\nframework pushes VTS agent and VTS shell driver binaries to each Android device\nand establishes TCP connections to the VTS agents on those devices.\n\nTo execute a shell command, the host-side Python script makes a function\ncall to the ShellMirror object inside AndroidDevice object. The ShellMirror\nobject packs the shell command texts into a\n[protobuf](https://developers.google.com/protocol-buffers/)\nmessage and sends it (via the TCP channel) to the VTS agent on the Android\ndevice. The agent running on device then forwards the shell command to VTS shell\ndriver via the Unix socket.\n\nWhen the VTS shell driver receives a shell command, it executes the command\nvia [nohup](https://en.wikipedia.org/wiki/Nohup) on\nthe device shell to prevent hanging. Stdout, stderr, and return code are then\nretrieved from `nohup` and sent back to VTS agent. Finally, the agent\nreplies to the host by wrapping the command result(s) into a\n`protobuf` message.\n\n### Advantages\n\nThe advantages of using the VTS shell driver instead of `adb\nshell` include:\n\n- **Reliability.** The VTS shell driver uses `nohup` to execute commands on default setting. As VTS tests are mostly lower level HAL and kernel tests, `nohup` ensures shell commands do not hang during execution.\n- **Performance** . While the `adb shell` command caches some results (such as listing files in a directory) it has a connection overhead when performing tasks such as executing a test binary. VTS shell driver maintains an active connection throughout the test so the only overhead is USB communication. In our testing, using VTS shell driver to execute a command with 100 calls to an empty gtest binary is about 20 percent faster than using `adb shell`; the actual difference is larger since VTS shell communication has extensive logging.\n- **State-keeping** . The VTS shell driver maintains a terminal session for each terminal name (default terminal name is *default*). Environment variables set in one terminal session are available only to subsequent commands in the same session.\n- **Extendable**. Shell command communications between VTS framework and device driver are wrapped in protobuf to enable potential compression, remoting, encryption, etc. in the future. Other possibilities for improving performance are also available, including device-side result parsing when the communication overhead becomes larger than result string parsing.\n\n### Disadvantages\n\nThe disadvantages of using the VTS shell driver instead of `adb\nshell` include:\n\n- **Additional binaries**. VTS agent files must be pushed to device and cleaned up after test execution.\n- **Requires active connection** . If the TCP connection between host and agent is lost during testing (due to USB disconnection, port shutdown, device crash, etc.) either intentionally or unintentionally, a shell command cannot be transmitted to the VTS agent. Even with automatic switching to `adb shell`, the result and state of the command before disconnection would be unknown.\n\n### Examples\n\nExamples of using shell commands in a VTS host-side Python test script:\n\n- Get an Android device object: \n\n ```\n self.device = self.android_devices[0]\n ```\n- Get an shell object for the selected device: \n\n ```\n self.shell = self.device.shell\n ```\n- Issue a single shell command: \n\n ```\n results = self.shell.Execute(‘ls')\n ```\n- Issue a list of shell commands: \n\n ```\n results = self.shell.Execute([‘cd /data/local/tmp', ‘ls'])\n ```\n\n### Command result object\n\nThe return object from shell command execution is a dictionary containing the\nkeys `stdouts`, `stderrs`, and `return_codes`.\nRegardless of whether the shell command is provided as a single string or a list\nof command strings, each value of the result dictionary is always a list.\n\nTo verify the return code of a list of commands, the test script must check\nthe indices. Example: \n\n```\nasserts.assertFalse(any(results[‘return_codes']), ‘some command failed.')\n```\n\nAlternatively, the script can check each command index individually.\nExample: \n\n```\nasserts.assertEqual(results[‘return_codes'][0], 0, ‘first command failed')\n\nasserts.assertEqual(results[‘return_codes'][1], 0, ‘second command failed')\n```"]]