3 votes

Comment exécuter un script en arrière-plan depuis le shell adb ?

J'ai un problème avec le tethering USB sur mon téléphone Nougat rooté (LineageOS). Après un certain temps, le téléphone arrête le tethering USB. Pour corriger cela, j'exécute le script suivant comme ceci :

adb shell
su
nohup sh tether.sh &
exit
exit

tether.sh

#!/system/bin/sh
service list
while true;
do
  if ! pidof -s dnsmasq > /dev/null
  then
    echo -n "Connectivity lost at "
    date -u +%FT%TZ
    echo "Waiting 3 seconds..."
    sleep 3
    echo "Calling ConnectivityManager.setUsbTethering(false)"
    service call connectivity 33 i32 0 2>&1
    sleep 3
    echo "Calling ConnectivityManager.setUsbTethering(true)"
    service call connectivity 33 i32 1 2>&1
    echo "Waiting 3 seconds..."
  fi
  sleep 3
done

Problème : si j'utilise nohup mon appel à service call connectivity échoue avec un service non trouvé. Et je mets service list au dessus du script qui renvoie Found 0 services: . Cependant, les mêmes commandes fonctionnent lorsqu'elles sont exécutées directement à partir de adb shell; su .

Pourquoi service call ne fonctionne pas dans ce script de fond ? A-t-il besoin de la même tty pour travailler ?

4voto

Irfan Latif Points 16863

Les processus reçoivent signaux d'autres processus ou du noyau comme un avertissement ou une demande de changement d'état. Les processus récepteurs peuvent bloc , ignorer ou attraper signaux, sauf SIGKILL qui fait ce que son nom indique. Un processus reçoit SIGHUP (signal de raccrochage) lorsque son terminal de contrôle (virtuel ou pseudo) se déconnecte ou que son processus de contrôle (qui est généralement un shell) se termine. Cité dans adb shell source :

Les PTY envoient automatiquement SIGHUP au processus côté esclave lorsque le côté maître du PTY se ferme.

* Voir Terminaux et shells sur Android pour plus de détails sur les PTYs

Le processus peut alors traiter le signal pour continuer son exécution ou est simplement tué par le noyau.

nohup fait tourner un processus (généralement en arrière-plan) en ignorant simplement les éléments suivants SIGHUP même si la borne de commande se ferme. De plus, si les FD 0 , 1 y 2 du processus sont attachés au terminal, nohup redirige vers STDIN de /dev/null y STDOUT / STDERR a nohup.out archivo.

La fonction intégrée d'Android /system/bin/nohup a une mauvaise mise en œuvre comme beaucoup d'autres applets de toybox . Il remplace STDIN avec rien et laisse STDERR attaché à la borne. Ainsi, tous les outils de ligne de commande de l'interpréteur de commandes qui sont liés à l'environnement de travail de l'utilisateur. system_server se comportent de manière inattendue en raison de l'absence de FD 0 .

La solution consiste à utiliser nohup par exemple, à partir de busybox ou de do :

nohup tether.sh </dev/null &

Ou sans nohup :

tether.sh </dev/null &>/sdcard/usb.log &

Afin d'être sûr qu'un programme ignore SIGHUP , ajouter trap '' 1 au script au-dessus du programme à exécuter. Mais ce n'est pas nécessaire avec le MirBSD Korn Shell par défaut d'Android ( /system/bin/sh ) qui n'envoie pas SIGHUP à tous les travaux (processus enfants) de la même session, c'est-à-dire attachés au même terminal. Ainsi, nohup ou trap n'est pas essentiellement nécessaire, que le shell sorte ou soit tué.

Ensuite, mksh ne se détache pas complètement du ou des terminaux car en plus de STDIN/OUT/ERR il s'attache à /dev/tty directement ( réf. ) . Donc détacher les FDs 0/1/2 ne suffit pas. Il existe cependant un mode démon qui détache complètement la commande du terminal :

/system/bin/sh -T- tether.sh

Aussi mksh débloque tous les signaux bien que cela ne soit pas pertinent ici.

bash permet une meilleure gestion des tâches ; l'utilisateur peut configurer avec huponexit si oui ou non il faut toujours envoyer SIGHUP à tous les emplois à la sortie ( réf. ) . La fonction intégrée de Bash disown peut être utilisée pour exclure des travaux de la réception de signaux.

Pour maintenir l'exécution du script au premier plan, un multiplexeur comme tmux ou screen peut être utilisé. C'est ce que je fais, en particulier avec su les binaires des solutions d'enracinement qui ne se détachent pas (en raison de l'implémentation limitée des pseudo-terminaux), lorsqu'un programme est exécuté en arrière-plan. Voir cette question pour les détails.

RELATION : Comment lancer un exécutable au démarrage et le maintenir en fonctionnement ?

androidalle.com

AndroidAlle est une communauté de androiders où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X