À partir d'un shell sur mon PC, je peux exécuter adb Shell cmd package list packages
, et obtenez une liste de tous les packages installés. Je voudrais exécuter ceci et des commandes similaires localement sur mon Android (Nexus 6P) dans un émulateur de terminal (utilisant actuellement Termux).
Si j'ouvre le même shell avec /system/bin/sh
, puis essayez d'exécuter /system/bin/cmd package list packages
, rien ne se passe (pas d'erreurs, ne sort rien et recharge l'Invite).
Si je lance /system/bin/cmd -l
la liste des options apparaît comme prévu. $PATH
et $LD_LIBRARY_PATH
sont les mêmes dans les deux environnements. Une différence majeure est que echo $USER
renvoie "Shell" de adb Shell
, mais renvoie mon nom d'utilisateur local à partir de /system/bin/sh
lancé depuis Termux.
Existe-t-il un moyen de reproduire le comportement des commandes exécutées à partir de adb Shell
dans un émulateur de terminal localement sur Android?
Modifier: mon appareil est enraciné et je suis d'accord avec les solutions root uniquement.
Je n'ai pas de périphérique Nougat enraciné à portée de main, mais quelque chose comme ce qui suit peut être une approximation assez proche de adb Shell
(En supposant que vous utilisez 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
Je l'ai (très brièvement) testé depuis Termux sur un appareil Marshmallow enraciné.
Élaborer:
-i
est utilisé pour commencer avec un environnement videUSER=Shell
N'est pas spécifiquement requis, mais pour une raison quelconque su
refuse de fonctionner avec un environnement complètement vide$(PATH=/system/xbin:/system/bin:/su/bin:/sbin:/magisk/.core/bin which su)
pointe vers le chemin complet du binaire su sur votre appareil et peut être codé en dur si vous préférezShell
demande au binaire su
de se connecter en tant qu'utilisateur Shell (identique à adb Shell
)--context u:r:Shell:s0
Définit le contexte SELinux approprié--Shell /system/bin/sh
Demande à SuperSU d'utiliser le Shell système plutôt que son propre sush
ShellUne autre option serait d'exécuter réellement adb à partir du périphérique, en se connectant à lui-même via TCP. Si vous avez besoin d'une fonctionnalité qui n'est disponible que via adb (par exemple, dans mon cas, c'était adb forward
), Cela peut être votre seule option. Malheureusement, ce n'est pas particulièrement pratique.
Je n'ai pas réussi à trouver de succès avec les binaires adb disponibles publiquement, donc je le construis moi-même avec quelques changements mineurs. Vous pouvez voir les sources que j'ai utilisées et les modifications que j'ai apportées à https://github.com/shakalaca/fastboot-adb-Android et https://github.com/brbsix/ fastboot-adb-Android , respectivement.
Une fois que vous avez installé adb, voici une liste abrégée des commandes que j'ai utilisées pour me connecter à l'appareil:
# 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
Éteindre:
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
Le problème est Termux. De par sa conception, Termux exécute uniquement (ou est principalement?) Les programmes de ligne de commande Linux que vous installez à partir de Termux à l'aide d'apt ou de la nouvelle interface de gestion de packages "native", par ex. installer apt bsdtar. Ce dont vous avez besoin pour exécuter les commandes adb Shell est un émulateur de terminal qui peut vraiment accéder au système de fichiers sous-jacent Android, pas seulement au Termux qui est pratiquement un chroot sauf pour le fait qu'il est conscient qu'il ne l'est pas exécution de commandes à partir de la racine du système de fichiers /.
Comme test simple, exécutez la commande suivante:
which ls
Il devrait renvoyer quelque chose comme /system/bin/ls
. Mais s'il renvoie quelque chose comme /data/data/com.termux/files/usr/bin/applets/ls
alors vous devez changer votre émulateur de terminal pour autre chose. Je soupçonne que Termux a été conçu pour prendre en compte les politiques d'exécution Shell plus restrictives que Google a mises en place après KitKat ou Android 4.X.
La distribution Android que j'utilise, LineageOS 14.1, est livrée avec un émulateur Shell intégré qui me permet d'exécuter des commandes trouvées dans/system/bin/ls.
EDIT J'ai répondu à l'origine sans la balise termux
. Cela a fonctionné pour moi tout en essayant d'exécuter des commandes Shell sur un émulateur Vanilla et j'ai vu cette question lors de la recherche, j'ai donc essayé d'y répondre différemment.
Vous l'aviez presque là dans votre question. Il vous suffit d'exécuter 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();
}
Si result == 0
les commandes ont réussi, sinon sinon