[英]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 $USER
從adb 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-android和https://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 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
則命令成功,否則,否則
只需編寫不帶前綴adb
的普通命令
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.