自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
裝置殼層指令
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
在 VTS 測試期間,shell 指令會用於執行目標端測試二進位檔,以便取得/設定屬性、環境變數和系統資訊,以及啟動/停止 Android 架構。您可以使用 adb shell
指令或在裝置上執行的 VTS 殼層驅動程式 (建議) 執行 VTS 裝置殼層指令。
使用 ADB 殼層
在測試期間需要關閉 USB 連接埠或重新啟動裝置的測試必須使用 ADB 殼層,因為在沒有持續 USB 連線的情況下,VTS 殼層驅動程式無法使用。您可以透過 Python 測試指令碼中的 AndroidDevice
物件叫用 ADB 殼層。例如:
- 取得 Android 裝置物件:
self.device = self.android_devices[0]
- 發出單一殼層指令:
result = self.device.adb.shell(‘ls')
使用 VTS 殼層驅動程式
VTS shell 驅動程式是裝置上執行的代理程式二進位檔,可執行 shell 指令。根據預設,如果驅動程式在裝置上執行,VTS 會使用殼層驅動程式,因為這個方法的延遲時間比使用 adb
shell
指令時短。

圖 1. VTS shell 驅動程式。
VTS 架構支援多裝置測試,在這種測試中,每部 Android 裝置都會在基礎執行器中以 AndroidDevice 物件表示。根據預設,VTS 架構會將 VTS 代理程式和 VTS 殼層驅動程式二進位檔推送至每部 Android 裝置,並在這些裝置上建立與 VTS 代理程式的 TCP 連線。
如要執行殼層指令,主機端 Python 指令碼會對 AndroidDevice 物件中的 ShellMirror 物件發出函式呼叫。ShellMirror 物件會將殼層指令文字打包成 protobuf 訊息,並透過 TCP 通道傳送至 Android 裝置上的 VTS 代理程式。接著,在裝置上執行的代理程式會透過 Unix 套接字,將殼層指令轉送至 VTS 殼層驅動程式。
當 VTS 殼層驅動程式收到殼層指令時,會透過 nohup 在裝置殼層上執行指令,以免發生當機情形。接著,系統會從 nohup
擷取 stdout、stderr 和傳回碼,並傳回 VTS 代理程式。最後,代理程式會將指令結果包裝成 protobuf
訊息,回覆主機。
優點
使用 VTS 殼層驅動程式而非 adb
shell
的好處包括:
- 可靠性:VTS 殼層驅動程式會使用
nohup
在預設設定下執行指令。由於 VTS 測試大多是較低層級的 HAL 和核心測試,nohup
可確保殼層指令不會在執行期間停止運作。
- 效能。雖然
adb shell
指令會快取部分結果 (例如列出目錄中的檔案),但在執行測試二進位檔等工作時,會有連線額外負擔。VTS 殼層驅動程式會在整個測試期間維持有效連線,因此唯一的開銷就是 USB 通訊。在我們的測試中,使用 VTS shell 驅動程式執行包含 100 次對空白 gtest 二進位檔呼叫的命令,比使用 adb shell
快上約 20%;由於 VTS shell 通訊會產生大量記錄,實際差異會更大。
- 狀態維護:VTS 殼層驅動程式會為每個終端機名稱維護一個終端機工作階段 (預設終端機名稱為「預設」)。在一個終端機工作階段中設定的環境變數,僅適用於同一個工作階段中的後續指令。
- 可擴充。VTS 架構和裝置驅動程式之間的殼層指令通訊會以 protobuf 包裝,以便日後啟用可能的壓縮、遠端連線、加密等功能。您也可以透過其他方式改善效能,例如在通訊額外負擔大於結果字串剖析時,使用裝置端的結果剖析。
缺點
使用 VTS 殼層驅動程式而非 adb
shell
的缺點包括:
- 其他二進位檔。測試執行後,必須將 VTS 服務專員檔案推送至裝置並清理。
- 必須連上網路。如果主機和代理程式之間的 TCP 連線在測試期間遺失 (因 USB 連線中斷、埠關閉、裝置當機等原因),則無法將殼層指令傳送至 VTS 代理程式。即使自動切換至
adb shell
,系統仍無法得知中斷連線前的指令結果和狀態。
範例
在 VTS 主機端 Python 測試指令碼中使用殼層指令的範例:
- 取得 Android 裝置物件:
self.device = self.android_devices[0]
- 取得所選裝置的殼層物件:
self.shell = self.device.shell
- 發出單一殼層指令:
results = self.shell.Execute(‘ls')
- 發出殼層指令清單:
results = self.shell.Execute([‘cd /data/local/tmp', ‘ls'])
指令結果物件
執行殼層指令後傳回的物件是字典,其中包含 stdouts
、stderrs
和 return_codes
鍵。無論殼層指令是以單一字串或指令字串清單的形式提供,結果字典的每個值一律為清單。
如要驗證指令清單的傳回碼,測試指令碼必須檢查索引。例子:
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 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間: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```"]]