繁体   English   中英

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

[英]How do I run "adb shell" commands in a terminal emulator locally on an Android device?

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

如果我使用/system/bin/sh打开相同的外壳,然后尝试运行/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 的解决方案。

我没有方便的植根的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

我(非常简短地)在有根的棉花糖设备上从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 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

问题是Termux。 根据设计,Termux仅运行(或主要是?)使用apt或较新的“本机”程序包管理界面从Termux中安装的Linux命令行程序,例如apt install bsdtar。 运行adb shell命令所需的是一个终端仿真器,它可以真正访问基础的Android文件系统,而不仅仅是Termux(实际上是chroot),因为它知道它不是从文件系统root /运行命令。

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

    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带有内置的外壳模拟器,可让我运行/ system / bin / ls中的命令。

所以我最近尝试了这个......如果你已经扎根,你可以使用终端模拟器。

  • 然后是你想要的没有“adb shell”部分的命令。

我尝试了命令“adb shell dumpsys deviceidle force-idle”以强制设备进入瞌睡。 我通过终端模拟器在设备上执行此操作:“dumpsys deviceidle force-idle”并且它确实生效了。 dumpsys batterystats 命令也有效。

小心带有大量文本输出的命令,因为屏幕会被输出淹没并且在一段时间内没有响应。

编辑我最初回答这个问题时没有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则命令成功,否则,否则

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM