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

rjd*_*ang 5 shell android adb termux

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

如果我使用打开了同一外壳/system/bin/sh,然后尝试运行/system/bin/cmd package list packages,则不会发生任何事情(没有错误,仅输出任何内容并重新加载提示)。

如果我运行/system/bin/cmd -l,选项列表将按预期显示。$PATH并且$LD_LIBRARY_PATH在两种环境中都相同。一个主要区别是,它echo $USER从中返回“ shell” adb shell,但从/system/bin/shTermux中启动后返回我的本地用户名。

有什么方法可以复制adb shell在Android本地终端仿真器中运行的命令的行为吗?

编辑:我的设备已植根,我可以使用仅根的解决方案。

小智 6

问题出在 Termux 上。根据设计,Termux 只运行(或大部分?)您使用 apt 或较新的“本机”包管理界面(例如 apt install bsdtar)从 Termux 内安装的 Linux 命令行程序。运行 adb shell 命令需要的是一个终端仿真器,它可以真正访问底层 Android 文件系统,而不仅仅是 Termux,它实际上是一个 chroot 保存,因为它知道自己没有从文件系统 root / 运行命令。

作为一个简单的测试,运行以下命令:

    which ls
Run Code Online (Sandbox Code Playgroud)

它应该返回类似的东西/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 中的命令。


Six*_*Six 5

我手边没有带根的 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
Run Code Online (Sandbox Code Playgroud)

我(非常简短地)在有根棉花糖设备上从 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 使用系统外壳而不是它自己的sush外壳

另一种选择是从设备实际运行 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
Run Code Online (Sandbox Code Playgroud)

去关机:

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
Run Code Online (Sandbox Code Playgroud)