web-dev-qa-db-fra.com

Comment exécuter localement les commandes "adb Shell" dans un émulateur de terminal sur un appareil Android?

À 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.

5
user2571203

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:

  • le drapeau -i est utilisé pour commencer avec un environnement vide
  • USER=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érez
  • Shell 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 Shell

Une 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
3
Six

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.

3

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

0
Chisko