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?