3 votos

¿Cómo ejecutar un script en segundo plano desde adb shell?

Tengo un problema con el tethering USB en mi teléfono Nougat rooteado (LineageOS). Después de algún tiempo el teléfono deja de USB tethering. Para solucionarlo ejecuto el siguiente script así:

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

Problema: Si utilizo nohup mi llamada a service call connectivity falla con el servicio no encontrado. Y pongo service list sobre el script que devuelve Found 0 services: . Sin embargo, los mismos comandos funcionan cuando se ejecutan directamente desde adb shell; su .

Por qué service call no funciona dentro de este script de fondo? ¿Necesita el mismo tty para trabajar?

4voto

Jack Wade Puntos 231

Los procesos reciben señales de otros procesos o del kernel como una advertencia o como una solicitud para realizar algún cambio de estado. Los procesos receptores pueden bloque , ignorar o captura señales, excepto SIGKILL que hace lo que dice su nombre. Un proceso recibe SIGHUP (señal de colgado) cuando su terminal de control (virtual o pseudo) se desconecta o su proceso de control (que suele ser un shell) termina. Citado de adb shell fuente :

Los PTYs envían automáticamente SIGHUP al proceso del lado esclavo cuando el lado maestro del PTY se cierra

* Ver Terminales y conchas en Android para más detalles sobre los PTY

El proceso puede entonces manejar la señal para continuar su ejecución o simplemente es matado por el kernel.

nohup hace que un proceso se ejecute (normalmente en segundo plano) simplemente ignorando SIGHUP incluso si el terminal de control se cierra. Además, si los FD 0 , 1 y 2 del proceso se adjuntan al terminal, nohup redirecciona a STDIN de /dev/null y STDOUT / STDERR a nohup.out archivo.

El sistema integrado de Android /system/bin/nohup tiene alguna mala implementación como muchos otros applets de toybox . Sustituye a STDIN sin nada y deja STDERR conectado al terminal. Así que todas las herramientas de línea de comandos del shell que están relacionadas con system_server se comportan de forma inesperada por no tener FD 0 .

La solución es utilizar nohup por ejemplo, de busybox o do:

nohup tether.sh </dev/null &

O sin nohup :

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

Para que un programa ignore SIGHUP , añadir trap '' 1 a la secuencia de comandos por encima del programa a ejecutar. Pero no es necesario con el MirBSD Korn Shell por defecto de Android ( /system/bin/sh ) que no envía SIGHUP a todos los trabajos (procesos hijos) en la misma sesión, es decir, unidos a la misma terminal. Así que nohup o trap no es esencialmente necesario, ya sea que la cáscara salga o sea asesinada.

En segundo lugar mksh no se desprende completamente de la(s) terminal(es) porque además de STDIN/OUT/ERR se adhiere a /dev/tty directamente ( ref ) . Así que separar los FDs 0/1/2 no es suficiente. Sin embargo, hay un modo demonio que separa completamente el comando de la terminal:

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

También mksh desbloquea todas las señales aunque no es relevante en este caso.

bash proporciona una mejor gestión del trabajo; el usuario puede configurar con huponexit si enviar siempre o no SIGHUP a todos los trabajos al salir ( ref ) . El sistema de Bash disown se puede utilizar para excluir trabajos de la recepción de señales.

Para mantener el script en primer plano, un multiplexor como tmux o screen se puede utilizar. Eso es lo que hago, particularmente con su binarios de soluciones del rooting que no se desprenden (debido a la implementación limitada de pseudoterminales), cuando un programa se ejecuta en segundo plano. Véase este tema para más detalles.

RELACIONADO: ¿Cómo ejecutar un ejecutable en el arranque y mantenerlo en funcionamiento?

1 votos

-T- es mi nuevo juguete, no lo conocía. Sintaxis simple y hace lo que necesito. Muy elaborado gracias.

PreguntAndroid.com

PreguntAndroid es una comunidad de usuarios de Android en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X