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

14

我可以在我的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权限,并且我可以接受只有root权限的解决方案。


请参考以下链接:https://github.com/termux/termux-app/issues/77 - Amit Kumar Khare
谢谢提供链接。然而,我认为该链接实际上是试图做与我想要的相反的事情:从adb模拟termux的行为。我实际上想要在设备本地运行的shell中模拟从adb shell运行的命令的行为。我的困惑在于,我正在使用相同的二进制文件和相同的shell二进制文件在同一设备上运行,并获得不同的输出(在本地运行时技术上没有输出)。 - user2571203
5个回答

6
问题出在Termux上。按设计,Termux仅运行您从Termux内部使用apt或较新的“本地”软件包管理界面安装的Linux命令行程序,例如apt install bsdtar。要运行adb shell命令,您需要一个终端仿真器,它可以真正访问底层Android文件系统,而不仅是Termux,它实际上是chroot的,除了它知道它没有从文件系统根目录/运行命令。
作为简单测试,请运行以下命令:
    which ls

应该返回类似于/system/bin/ls的结果。但如果它返回类似于/data/data/com.termux/files/usr/bin/applets/ls的结果,则需要更换终端模拟器。我怀疑Termux是为考虑KitKat或Android 4.X之后谷歌实施的更加严格的shell执行策略而设计的。我使用的Android版本是LineageOS 14.1,它自带一个内置的shell模拟器,允许我运行在/system/bin/ls中找到的命令。

6

我手头没有一个已经root的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

感谢您详细的回复。我不知道其中一些设置/命令。我正在使用Magisk进行root,但是root似乎正常工作。不幸的是,这个命令对于“cmd”命令仍然给出了相同的结果。它什么也没有返回。我在Nexus 5x上运行Nougat进行尝试,以确保它不是设备问题,但是得到了相同的结果:在adb shell中可以工作,在Termux中使用您的命令则为null。这可能是Nougat引入的更改? - user2571203
1
在我的Pie上运行良好。 - divykj
1
非常感谢!正是我在寻找的!ADB命令在Samsung Edge S6 Android 7.0 Nougat上使用Termux工作了! - idontknow

4

我最近尝试了这个方法...如果你的设备已经root,你可以使用终端模拟器。

  • 输入su命令
  • 然后输入想要执行的命令,不需要包含"adb shell"部分。

我尝试了命令"adb shell dumpsys deviceidle force-idle"来让设备进入doze模式。我通过终端模拟器在设备上执行了以下命令:"dumpsys deviceidle force-idle",并且它确实生效了。同时,命令"dumpsys batterystats"也起作用了。

请注意,对于输出大量文本的命令,屏幕会被输出信息淹没,并且可能会在一段时间内无响应。


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 ,则命令执行成功,否则失败。

它告诉我没有连接任何设备(也没有找到任何设备)。你知道为什么吗? - Edw590
@DADi590 我假设你的设备没有启用 USB 调试。 - Chisko
@Chrisko,它确实有用。这就是为什么我不明白为什么它不起作用。 - Edw590
如果adb devices没有任何输出,你可以查看一些答案:https://dev59.com/j2Uo5IYBdhLWcg3w2CaJ - Chisko
啊,但是它在电脑上可以运行。只是在模拟器上不行。我会再深入搜索一下的。谢谢。 - Edw590

-2
  • 仅适用于已root的安卓设备
  • 必须安装Busybox(尽管您可以尝试不安装)

只需编写正常命令,无需前缀adb


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接