ตั้งแต่วันที่ 27 มีนาคม 2025 เป็นต้นไป เราขอแนะนำให้ใช้ android-latest-release
แทน aosp-main
เพื่อสร้างและมีส่วนร่วมใน AOSP โปรดดูข้อมูลเพิ่มเติมที่หัวข้อการเปลี่ยนแปลงใน AOSP
คำสั่งเชลล์ของอุปกรณ์
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
ในระหว่างการทดสอบ VTS ระบบจะใช้คำสั่งเชลล์เพื่อเรียกใช้ไบนารีทดสอบฝั่งเป้าหมาย เพื่อรับ/ตั้งค่าพร็อพเพอร์ตี้ ตัวแปรสภาพแวดล้อม และข้อมูลระบบ รวมถึงเพื่อเริ่ม/หยุดเฟรมเวิร์ก Android คุณสามารถเรียกใช้คำสั่งเชลล์ของอุปกรณ์ VTS โดยใช้คำสั่ง adb shell
หรือไดรเวอร์เชลล์ VTS ที่ทำงานบนอุปกรณ์ (แนะนำ)
ใช้เชลล์ ADB
การทดสอบที่ต้องปิดพอร์ต USB หรือรีบูตอุปกรณ์ระหว่างการทดสอบต้องใช้เชลล์ ADB เนื่องจากไดรเวอร์เชลล์ VTS จะใช้งานไม่ได้หากไม่มีการเชื่อมต่อ USB แบบถาวร คุณสามารถเรียกใช้เชลล์ ADB จากออบเจ็กต์ AndroidDevice
ในสคริปต์ทดสอบ Python ตัวอย่าง
- รับออบเจ็กต์อุปกรณ์ Android
self.device = self.android_devices[0]
- ออกคำสั่ง Shell รายการเดียว ดังนี้
result = self.device.adb.shell(‘ls')
ใช้ไดรเวอร์เชลล์ VTS
โปรแกรมควบคุมเชลล์ VTS คือไบนารีของตัวแทนที่ทำงานในอุปกรณ์และดำเนินการตามคำสั่งเชลล์ โดยค่าเริ่มต้น VTS จะใช้ไดรเวอร์เชลล์หากไดรเวอร์ดังกล่าวทำงานอยู่ในอุปกรณ์ เนื่องจากวิธีการนี้มีความล่าช้าน้อยกว่าการใช้คําสั่ง adb
shell

รูปที่ 1 ไดรเวอร์เชลล์ VTS
เฟรมเวิร์ก VTS รองรับการทดสอบหลายอุปกรณ์ โดยอุปกรณ์ Android แต่ละเครื่องจะแสดงเป็นออบเจ็กต์ AndroidDevice ใน Base Runner โดยค่าเริ่มต้น เฟรมเวิร์ก VTS จะพุชไบนารีของตัวแทน VTS และไดรเวอร์เชลล์ VTS ไปยังอุปกรณ์ Android แต่ละเครื่อง และสร้างการเชื่อมต่อ TCP กับตัวแทน VTS ในอุปกรณ์เหล่านั้น
หากต้องการเรียกใช้คำสั่ง Shell สคริปต์ Python ฝั่งโฮสต์จะเรียกใช้ฟังก์ชันกับออบเจ็กต์ ShellMirror ภายในออบเจ็กต์ AndroidDevice ออบเจ็กต์ ShellMirror จะแพ็กข้อความคำสั่งเชลล์เป็นข้อความ protobuf แล้วส่ง (ผ่านช่องทาง TCP) ไปยังตัวแทน VTS ในอุปกรณ์ Android จากนั้น Agent ที่ทำงานในอุปกรณ์จะส่งต่อคำสั่งเชลล์ไปยังไดรเวอร์เชลล์ VTS ผ่านซ็อกเก็ต Unix
เมื่อโปรแกรมควบคุมเชลล์ VTS ได้รับคำสั่งเชลล์ ระบบจะดำเนินการตามคำสั่งผ่าน nohup ในเชลล์ของอุปกรณ์เพื่อป้องกันการหยุดทำงาน จากนั้นระบบจะดึงข้อมูล Stdout, stderr และรหัสผลลัพธ์จาก nohup
และส่งกลับไปยังตัวแทน VTS สุดท้าย ตัวแทนจะตอบกลับโฮสต์โดยรวมผลลัพธ์ของคำสั่งไว้ในข้อความ protobuf
ข้อดี
ข้อดีของการใช้ไดรเวอร์เชลล์ VTS แทน adb
shell
มีดังนี้
- ความน่าเชื่อถือ โปรแกรมควบคุมเชลล์ VTS ใช้
nohup
เพื่อเรียกใช้คําสั่งในการตั้งค่าเริ่มต้น เนื่องจาก VTS ส่วนใหญ่เป็นการทดสอบ HAL และเคอร์เนลระดับล่าง nohup
จึงตรวจสอบว่าคำสั่งเชลล์ไม่ค้างระหว่างการดำเนินการ
- ประสิทธิภาพ แม้ว่าคำสั่ง
adb shell
จะแคชผลลัพธ์บางอย่าง (เช่น แสดงรายการไฟล์ในไดเรกทอรี) แต่ก็มีค่าใช้จ่ายเพิ่มเติมในการเชื่อมต่อเมื่อทำงานต่างๆ เช่น เรียกใช้ไบนารีทดสอบ โปรแกรมควบคุมเชลล์ VTS จะรักษาการเชื่อมต่อที่ใช้งานอยู่ตลอดการทดสอบ ดังนั้นค่าใช้จ่ายเพิ่มเติมเพียงอย่างเดียวคือการสื่อสารผ่าน USB จากการทดสอบของเรา การใช้ไดรเวอร์เชลล์ VTS เพื่อเรียกใช้คําสั่งที่มีการเรียก 100 ครั้งไปยังไบนารี gtest ว่างเปล่านั้นเร็วกว่าการใช้ adb shell
ประมาณ 20 เปอร์เซ็นต์ แต่ความแตกต่างจริงจะมากกว่านี้เนื่องจากการสื่อสารของเชลล์ VTS มีการบันทึกอย่างละเอียด
- การเก็บสถานะ โปรแกรมควบคุมเชลล์ VTS จะดูแลเซสชันเทอร์มินัลสำหรับชื่อเทอร์มินัลแต่ละชื่อ (ชื่อเทอร์มินัลเริ่มต้นคือ default) ตัวแปรสภาพแวดล้อมที่ตั้งค่าไว้ในเซสชันเทอร์มินัล 1 เซสชันจะใช้ได้กับคำสั่งที่ตามมาในเซสชันเดียวกันเท่านั้น
- ขยายได้ การสื่อสารคําสั่ง Shell ระหว่างเฟรมเวิร์ก VTS กับไดรเวอร์อุปกรณ์จะรวมอยู่ใน protobuf เพื่อให้สามารถบีบอัด เข้าถึงจากระยะไกล เข้ารหัส ฯลฯ ในอนาคต นอกจากนี้ คุณยังใช้วิธีอื่นๆ ในการปรับปรุงประสิทธิภาพได้ด้วย เช่น การแยกวิเคราะห์ผลลัพธ์ฝั่งอุปกรณ์เมื่อค่าใช้จ่ายเพิ่มเติมในการสื่อสารมีขนาดใหญ่กว่าการแยกวิเคราะห์สตริงผลลัพธ์
ข้อเสีย
ข้อเสียของการใช้ไดรเวอร์เชลล์ VTS แทน adb
shell
มีดังนี้
- ไบนารีเพิ่มเติม คุณต้องพุชไฟล์ตัวแทน VTS ไปยังอุปกรณ์และล้างข้อมูลหลังจากการทดสอบ
- ต้องมีการเชื่อมต่อที่ใช้งานอยู่ หากการเชื่อมต่อ TCP ระหว่างโฮสต์กับตัวแทนขาดหายไประหว่างการทดสอบ (เนื่องจากมีการยกเลิกการเชื่อมต่อ USB, การปิดพอร์ต, อุปกรณ์ขัดข้อง ฯลฯ) ไม่ว่าจะตั้งใจหรือไม่ตั้งใจ ระบบจะส่งคำสั่งเชลล์ไปยังตัวแทน VTS ไม่ได้ แม้ว่าจะมีการเปลี่ยนเป็น
adb shell
โดยอัตโนมัติ แต่ผลลัพธ์และสถานะของคําสั่งก่อนตัดการเชื่อมต่อจะไม่ทราบ
ตัวอย่าง
ตัวอย่างการใช้คำสั่งเชลล์ในสคริปต์ทดสอบ Python ฝั่งโฮสต์ VTS
- รับออบเจ็กต์อุปกรณ์ Android
self.device = self.android_devices[0]
- รับออบเจ็กต์เชลล์สําหรับอุปกรณ์ที่เลือก
self.shell = self.device.shell
- ออกคำสั่ง Shell รายการเดียว ดังนี้
results = self.shell.Execute(‘ls')
- ออกรายการคำสั่ง Shell ดังนี้
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 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"]],["อัปเดตล่าสุด 2025-07-27 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```"]]