如何在Android设备上本地运行终端模拟器中的“adb shell”命令?

时间:2017-10-29 22:03:45

标签: android shell adb termux

从我的PC上的shell中,我可以运行adb shell cmd package list packages,并获取所有已安装软件包的列表。我想在我的Android手机(Nexus 6P)本地运行这个和类似命令的终端仿真器(目前使用的是Termux)。

如果我用/system/bin/sh打开相同的shell,然后尝试运行/system/bin/cmd package list packages,则没有任何反应(没有错误,只输出任何内容并重新加载提示)。

如果我运行/system/bin/cmd -l,则选项列表会按预期显示。 $PATH$LD_LIBRARY_PATH在两种环境中都相同。一个主要区别是echo $USERadb shell返回“shell”,但返回从Termux发起的/system/bin/sh的本地用户名。

有没有办法在Android本地终端模拟器中复制从adb shell运行的命令的行为?

编辑: 我的设备已植根,我只使用root解决方案。

5 个答案:

答案 0 :(得分:3)

我没有方便的Nougat设备,但以下内容可能与adb shell足够接近(假设您使用的是SuperSU):

env -i USER=shell "$(PATH=/system/xbin:/system/bin:/su/bin:/sbin:/magisk/.core/bin which su)" shell --context u:r:shell:s0 --shell /system/bin/sh --command COMMAND

我(非常简短地)在一个有根的Marshmallow设备上从Termux测试它。

详细说明:

  • -i标志用于以空白环境开始
  • USER=shell并非特别要求,但出于某种原因su拒绝使用完全空的环境运行
  • $(PATH=/system/xbin:/system/bin:/su/bin:/sbin:/magisk/.core/bin which su)指向设备上su二进制文件的完整路径,如果您愿意,可以进行硬编码
  • shell指示su二进制文件以shell用户身份登录(与adb shell相同)
  • --context u:r:shell:s0设置适当的SELinux上下文
  • --shell /system/bin/sh指示SuperSU使用系统shell而不是它自己的sush shell

另一种选择是从设备实际运行adb,通过TCP连接到自身。如果您需要某些仅通过adb可用的功能(例如,在我的情况下它是adb forward),那么这可能是您唯一的选择。不幸的是,这不是特别方便。

我无法在任何公开的adb二进制文件中找到成功,因此我自己构建它并进行一些小的更改。您可以分别查看我使用的来源以及我在https://github.com/shakalaca/fastboot-adb-androidhttps://github.com/brbsix/fastboot-adb-android所做的更改。

安装adb后,这是我用来连接设备的命令的缩写列表:

# Add iptables rules to block external connections to port 9999'
su root iptables -N adbd
su root iptables -A adbd -i lo -p tcp -m tcp --dport 9999 -j ACCEPT
su root iptables -A adbd -p tcp -m tcp --dport 9999 -j DROP
su root iptables -A INPUT -j adbd

# Necessary in order to display authorization prompt
su shell setprop ro.debuggable 1

su shell setprop service.adb.tcp.port 9999

su root start adbd

adb connect 127.0.0.1:9999

adb wait-for-local-device

要关闭:

adb kill-server
su root stop adbd
su shell setprop ro.debuggable 0
su shell setprop service.adb.tcp.port 0
su root iptables -D INPUT -j adbd
su root iptables -F adbd
su root iptables -X adbd

答案 1 :(得分:3)

问题是Termux。根据设计,Termux仅运行(或主要是)使用apt或更新的" native"在Termux中安装的Linux命令行程序。包管理界面,例如apt安装bsdtar。运行adb shell命令所需要的是一个终端模拟器,它可以真正访问底层的Android文件系统,而不仅仅是一个基本上是chroot的Termux,因为它知道它没有运行来自文件系统根目录的命令/.

作为简单测试,请运行以下命令:

    which ls

它应该返回类似/system/bin/ls的内容。但如果它返回/data/data/com.termux/files/usr/bin/applets/ls之类的内容,那么你必须将终端模拟器更改为其他内容。我怀疑Termux旨在考虑到Google在KitKat或Android 4.X之后实施的限制性更强的shell执行策略。

我使用的Android发行版LineageOS 14.1附带了一个内置的shell模拟器,可以让我运行/ system / bin / ls中的命令。

答案 2 :(得分:2)

所以我最近尝试过此方法...如果您是root用户,则可以使用终端模拟器。

  • su
  • 然后使用您想要的命令,而无需“ adb shell”部分。

我尝试执行命令“ adb shell dumpsys deviceidle force-idle”以强制设备进入休眠状态。 我通过终端仿真器在设备上执行了以下操作: “ dumpsys deviceidle force-idle”确实生效。 dumpsys batterystats命令也起作用。

请谨慎使用带有大量文本输出的命令,因为屏幕会被输出淹没,并且在一段时间内无响应。

答案 3 :(得分:0)

编辑 我最初回答此问题时没有想到termux标记。这在尝试在香草仿真器上执行shell命令时对我有用,并且在研究时看到了这个问题,因此我尝试以不同的方式回答。

您的问题几乎已经存在。您只需要执行sh

int result = -1;
try {
    final Process shell = Runtime.getRuntime().exec("sh");
    final DataOutputStream commands = new DataOutputStream(shell.getOutputStream());
    commands.writeBytes("write a series");
    commands.writeBytes("of commands here");
    commands.writeBytes("exit\n");
    commands.flush();
    result = shell.waitFor();
  }
} catch (Exception e) {
  e.printStackTrace();
}

如果result == 0命令成功,则否则

答案 4 :(得分:-1)

  • 仅植根于android
  • 必须安装Busybox(尽管您可以尝试不使用它)

只需编写不带前缀adb的普通命令