JeffLIrion / adb_shell

A Python implementation of ADB with shell and FileSync functionality.
Apache License 2.0
543 stars 60 forks source link

A few lines to add "adb exec-out" support. #141

Closed T2hhbmEK closed 3 years ago

T2hhbmEK commented 3 years ago
from adb_shell.adb_device import AdbDeviceTcp as _AdbDeviceTcp, constants, exceptions

class AdbDeviceTcp(_AdbDeviceTcp):
    def exec(
        self,
        command,
        transport_timeout_s=None,
        read_timeout_s=constants.DEFAULT_READ_TIMEOUT_S,
        timeout_s=None,
        decode=True,
    ):
        if not self.available:
            raise exceptions.AdbConnectionError(
                "ADB command not sent because a connection to the device has not been established.  (Did you call `AdbDevice.connect()`?)"
            )

        return self._service(
            b"exec",  # send exec instead of shell
            command.encode("utf8"),
            transport_timeout_s,
            read_timeout_s,
            timeout_s,
            decode,
        )

I'd like to see this feature soon. XD. Sorry for not able to submit a PR myself.

JeffLIrion commented 3 years ago

Could you please post a log from an exec command with the log level set to debug. That way I can add a unit test for this function.

T2hhbmEK commented 3 years ago

Sorry, I am not familiar with adb debugging. I need more detailed information on how to get the log so I can help.

JeffLIrion commented 3 years ago

Python logs, not ADB logs. This should work:

import logging

logging.getLogger("adb_shell.adb_device").setLevel(logging.DEBUG)
logging.getLogger("adb_device").setLevel(logging.DEBUG)
T2hhbmEK commented 3 years ago
import logging
from adb_shell.adb_device import AdbDeviceTcp

logging.basicConfig(level=logging.INFO)
logging.getLogger("adb_shell.adb_device").setLevel(logging.DEBUG)
logging.getLogger("adb_device").setLevel(logging.DEBUG)
device = AdbDeviceTcp("127.0.0.1", 7555)
try:
    device.connect()
    r = device._service(b"exec", "echo TEST".encode("utf8"))
    print(r)
finally:
    device.close()
DEBUG:adb_shell.adb_device:bulk_write: b'CNXN\x00\x00\x00\x01\x00\x00\x10\x00\x16\x00\x00\x00\x07\x06\x00\x00\xbc\xb1\xa7\xb1'
DEBUG:adb_shell.adb_device:bulk_write: b'host::DESKTOP-70888G8\x00'
DEBUG:adb_shell.adb_device:bulk_read(24): b'CNXN\x00\x00\x00\x01\x00\x10\x00\x00L\x00\x00\x00\x08\x1c\x00\x00\xbc\xb1\xa7\xb1'
DEBUG:adb_shell.adb_device:bulk_read(76): b'device::ro.product.name=cancro;ro.product.model=MuMu;ro.product.device=x86;\x00'
DEBUG:adb_shell.adb_device:bulk_write: b'OPEN\x01\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\xde\x04\x00\x00\xb0\xaf\xba\xb1'
DEBUG:adb_shell.adb_device:bulk_write: b'exec:echo TEST\x00'
DEBUG:adb_shell.adb_device:bulk_read(24): b'OKAY\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6'
DEBUG:adb_shell.adb_device:bulk_read(24): b'WRTE\x14\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00J\x01\x00\x00\xa8\xad\xab\xba'
DEBUG:adb_shell.adb_device:bulk_read(5): b'TEST\n'
DEBUG:adb_shell.adb_device:bulk_write: b'OKAY\x01\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xb4\xbe\xa6'
DEBUG:adb_shell.adb_device:bulk_write: b''
DEBUG:adb_shell.adb_device:bulk_read(24): b'CLSE\x14\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba'
DEBUG:adb_shell.adb_device:bulk_write: b'CLSE\x01\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xb3\xac\xba'
DEBUG:adb_shell.adb_device:bulk_write: b''
TEST
T2hhbmEK commented 3 years ago

The difference between exec and shell is that shell will turn \n into \r\n.

JeffLIrion commented 3 years ago

Thanks, I can work with that.

From https://www.linux-magazine.com/Issues/2017/195/Ask-Klaus:

adb exec-out "<command>"

Run command on Android and capture its unfiltered binary output (stdout)

I think I'll keep the default value of decode=true for this function, although it seems like this will produce the same results as shell, aside from the \n vs. \r\n difference that you pointed out.

JeffLIrion commented 3 years ago

Closed via https://github.com/JeffLIrion/adb_shell/pull/142