2025년 3월 27일부터 AOSP를 빌드하고 기여하려면 aosp-main
대신 android-latest-release
를 사용하는 것이 좋습니다. 자세한 내용은 AOSP 변경사항을 참고하세요.
기기 셸 명령어
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
VTS 테스트 중에 셸 명령어는 타겟 측 테스트 바이너리를 실행하고 속성, 환경 변수 및 시스템 정보를 가져오거나 설정하고 Android 프레임워크를 시작하거나 중지하는 데 사용됩니다. VTS 기기 셸 명령어는 adb shell
명령어 또는 기기에서 실행되는 VTS 셸 드라이버(권장)를 사용하여 실행할 수 있습니다.
ADB 셸 사용
테스트 중에 USB 포트를 종료하거나 기기를 재부팅해야 하는 테스트의 경우 영구 USB 연결 없이는 VTS 셸 드라이버를 사용할 수 없으므로 ADB 셸을 사용해야 합니다. ADB 셸은 Python 테스트 스크립트의 AndroidDevice
객체에서 호출할 수 있습니다. 예:
VTS 셸 드라이버 사용
VTS 셸 드라이버는 기기에서 실행되고 셸 명령어를 실행하는 에이전트 바이너리입니다. 기본적으로 VTS는 셸 드라이버가 기기에서 실행 중인 경우 이 드라이버를 사용합니다. 이 방법이 adb
shell
명령어를 사용하는 것보다 지연 시간이 짧기 때문입니다.

그림 1. VTS 셸 드라이버
VTS 프레임워크는 각 Android 기기가 기본 실행자에서 AndroidDevice 객체로 표시되는 다중 기기 테스트를 지원합니다. 기본적으로 VTS 프레임워크는 VTS 에이전트와 VTS 셸 드라이버 바이너리를 각 Android 기기에 푸시하고, 그러한 기기에 있는 VTS 에이전트로 TCP 연결을 설정합니다.
셸 명령어를 실행하기 위해 호스트 측 Python 스크립트는 AndroidDevice 객체 내의 ShellMirror 객체를 함수 호출합니다. ShellMirror 객체는 셸 명령어 텍스트를 protobuf 메시지로 압축하여 TCP 채널을 통해 Android 기기의 VTS 에이전트에 보냅니다. 그러면 기기에서 실행 중인 에이전트가 Unix 소켓을 통해 셸 명령어를 VTS 셸 드라이버에 전달합니다.
VTS 셸 드라이버가 셸 명령어를 수신하면 중단 현상을 방지하기 위해 기기 셸에서 nohup을 통해 명령어를 실행합니다. 그러면 stdout, stderr 및 return code를 nohup
에서 가져오고 이를 VTS 에이전트로 다시 보냅니다. 마지막으로 에이전트는 명령어 결과를 protobuf
메시지로 래핑하여 호스트에 응답합니다.
장점
adb
shell
대신 VTS 셸 드라이버를 사용할 때의 장점은 다음과 같습니다.
- 안정성. VTS 셸 드라이버는
nohup
을 사용하여 기본 설정에서 명령어를 실행합니다. VTS 테스트는 대부분 하위 수준의 HAL 및 커널 테스트이기 때문에 nohup
에서 실행 중에 셸 명령어가 중단되지 않도록 보장합니다.
- 성능.
adb shell
명령어가 일부 결과(예: 디렉터리에 파일 나열)를 캐시하지만, 테스트 바이너리 실행과 같은 작업을 할 때 연결 오버헤드가 발생합니다. VTS 셸 드라이버는 테스트 전반에 걸쳐 활성 상태의 연결을 유지하기 때문에 USB 통신이 유일한 오버헤드입니다. 테스트에서 VTS 셸 드라이버를 사용하여 빈 gtest 바이너리를 100번 호출하는 방식으로 명령어를 실행하면 adb shell
을 사용하는 것보다 약 20% 더 빠른 것으로 나타났습니다. VTS 셸 통신에서는 로깅이 광범위하기 때문에 실제 차이는 더 큽니다.
- 상태 유지. VTS 셸 드라이버는 터미널 이름마다 터미널 세션을 유지합니다(기본 터미널 이름은 default임). 한 터미널 세션에 설정된 환경 변수는 동일한 세션의 후속 명령어에만 사용할 수 있습니다.
- 확장 가능성. VTS 프레임워크와 기기 드라이버 간의 셸 명령어 통신은 향후 잠재적인 압축과 원격 사용, 암호화 등이 가능하도록 protobuf로 래핑됩니다. 성능 개선을 위해 다른 방법도 사용할 수 있습니다. 예를 들면 통신 오버헤드가 결과 문자열 파싱보다 클 경우 기기 측 결과를 파싱할 수 있습니다.
단점
adb
shell
대신 VTS 셸 드라이버를 사용하는 때의 단점은 다음과 같습니다.
- 추가 바이너리. VTS 에이전트 파일을 기기에 푸시해야 하고 테스트 실행 후 정리해야 합니다.
- 활성 상태의 연결 필요. 테스트 중에 USB 연결 해제, 포트 종료, 기기 장애 등으로 인해 호스트와 에이전트 간의 TCP 연결이 의도적으로 또는 의도치 않게 끊어지면 셸 명령어를 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')
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2024-05-02(UTC)
[[["이해하기 쉬움","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"]],["최종 업데이트: 2024-05-02(UTC)"],[],[],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```"]]