簡體   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