
Debido al hecho de que los dispositivos móviles han tenido una amplia funcionalidad, las tareas de automatización pueden transferirse fácilmente a ellos. Y, lo mejor posible, cron es igual de bueno para ejecutarlos. Pero si cron toma un poco de tiempo en sistemas Linux "ordinarios", entonces un dispositivo Android requiere un trabajo más complicado para configurarlo.
Si está interesado en el tema de la automatización y desea que sus scripts de shell se inicien inmediatamente después de que se inicie el dispositivo, e incluso podría iniciarse con un temporizador, ¡bienvenido al gato!
Prólogo
Me dedico a la automatización de dispositivos móviles para Android. Y durante la ejecución de scripts automáticos, se producen muchas situaciones imprevistas, incluso si se utilizan los mismos dispositivos para las pruebas.
Problemas más populares:
0. El script de automatización no hace lo que querías.
1. La aplicación móvil se descarga automáticamente
2. Reinicio automático del teléfono
3. La aplicación móvil no se inicia automáticamente después de reiniciar
4. El módulo Wi-Fi se apaga aleatoriamente, no encuentra la red, no se conecta a la red
5. La red móvil desapareció repentinamente
6. El teléfono entró en modo de suspensión
7. El proxy se cayó o el servidor mismo o el servidor devolvió una respuesta extraña
Debido a esto, debe monitorear constantemente el dispositivo y detectar estas situaciones imprevistas.

Por lo tanto, llegué a la conclusión de que cron con los scripts "correctos" le permitirá rastrear fallas de software y restaurar el script de automatización o ejecutarlo nuevamente. Pero resultó que, aunque Android contiene el kernel de Linux, hay algunos matices especiales con los que tuve que lidiar. ¡Así que comencemos con la configuración!
Configuración de Cron
Personaliza el entorno
- Instale adb para acceder al dispositivo a través del shell utilizando un cable usb.
- Abrimos la sección Para desarrolladores . Para hacer esto, vaya a la sección Acerca del teléfono y haga algunos clics en el número de compilación o algo similar.
- Vamos a la sección Para desarrolladores y lo activamos. Conectamos el dispositivo a la computadora y permitimos el acceso en esta computadora a este dispositivo.
- Agregue root para su dispositivo. Las opciones más comunes son SuperSu , Magisk y Kingroot . Vaya a w3bsit3-dns.com y encuentre la opción raíz para su dispositivo. Lamentablemente, no hay una raíz universal.
- Instalamos BusyBox (también está en w3bsit3-dns.com, por ejemplo), ya que solo contiene un programa cron.
Ajuste de inicio manual
- Nos conectamos al teléfono usando adb shell (si adb no está registrado en su variable de entorno, luego agregue la ruta completa.
- Vaya al modo raíz con el comando su
- Verificamos la presencia del programa cron y vemos la configuración usando el comando crond -h
resultado de ejecucióncrond: invalid option -- h BusyBox v1.29.2-Stericson (2018-08-12 11:19:12 EDT) multi-call binary. Usage: crond -fbS -l N -d N -L LOGFILE -c DIR -f Foreground -b Background (default) -S Log to syslog (default) -l N Set log level. Most verbose 0, default 8 -d N Set log level, log to stderr -L FILE Log to FILE -c DIR Cron dir. Default:/var/spool/cron/crontabs
Como puede ver en la última línea, las instrucciones predeterminadas deben almacenarse en el directorio
/ var / spool / cron / crontabs , que no se crea automáticamente y si ejecutamos el comando
crond -b
y luego verifique si el proceso comenzó a través de
ps | grep crond
, entonces puede que no esté allí, porque no pudo obtener ninguna instrucción. Entonces ejecutemos el comando
crond -b -fd0
y ver cuál es el motivo. Lo más probable es que tenga un error similar:
crond: can't change directory to '/var/spool/cron/crontabs': No such file or directory
. En este caso, esto es normal, porque en el futuro, nosotros mismos indicaremos la ruta al archivo ejecutable crontab.
4. Cree un archivo crontab simple:
mkdir /data/crontab echo "*/1 * * * * echo 'text' >> /sdcard/test.txt" > /data/crontab/root
Ahora tenemos una tarea que cada minuto agregará la palabra
texto al archivo
/sdcard/test.txtLanzamos:
crond -b -fd0 -c /data/crontab
y obtenga el siguiente registro:
crond: crond (busybox 1.29.2-Stericson) started, log level 0 crond: ignoring file 'root' (no such user) ...
Por supuesto, es un poco sorprendente, porque si ejecutamos el
comando whoami, como resultado, devolverá
root .
5. Agregue el usuario root, ya que crond pregunta:
mount -o remount,rw /system; echo "root:x:0:0::/system/etc/crontabs:/system/bin/sh" >> /system/etc/passwd; mount -o remount,ro /system;
Debido a la falta de este archivo, me di cuenta de que en el sistema Android no está involucrado en absoluto. Si está seguro de dónde almacenará sus archivos crontab, puede reemplazar la línea
/ system / etc / crontabs con la que necesita. Ejecute el comando nuevamente
crond -b -fd0 -c /data/crontab
Y obtenemos lo siguiente:
crond: user:root entry:*/1 * * * * echo 'text' >> /sdcard/test.txt 111111111111111111111111111111111111111111111111111111111111 111111111111111111111111 11111111111111111111111111111111 111111111111 1111111 crond: wakeup dt=16 crond: file root: crond: line echo 'text' >> /sdcard/test.txt crond: job: 0 echo 'text' >> /sdcard/test.txt crond: can't change directory to '/system/etc/crontabs' crond: can't change directory to '/var/spool/cron': No such file or directory crond: USER root pid 12849 cmd echo 'text' >> /sdcard/test.txt
Aunque, según el registro, la tarea se registró en crond, pero en mi caso el archivo no se creó. El problema se puede resolver de manera muy simple:
mkdir -p /system/etc/crontabs
Bueno, él quiere que exista un directorio allí, ¿quiénes somos para prohibirlo? Comenzamos de nuevo y vemos:
crond: user:root entry:*/1 * * * * echo 'text' >> /sdcard/test.txt 111111111111111111111111111111111111111111111111111111111111 111111111111111111111111 11111111111111111111111111111111 111111111111 1111111 crond: wakeup dt=12 crond: file root: crond: line echo 'text' >> /sdcard/test.txt crond: job: 0 echo 'text' >> /sdcard/test.txt crond: child running /system/bin/sh crond: USER root pid 13033 cmd echo 'text' >> /sdcard/test.txt
Los errores desaparecieron y
apareció la línea
crond: child running / system / bin / sh . Finalmente, cron se ha terminado con éxito, ¡y puedes pasar a la segunda parte!
Descarga automática de script de shell
El sistema Linux tiene un directorio
init.d que es responsable del
inicio automático inmediatamente después del arranque del sistema, ¡así que intentemos de esta manera!
1. Compruebe si este directorio existe en su dispositivo (esto es
/etc/init.d o
/system/etc/init.d : esta es la misma partición montada, etc.). En mi caso, no lo es. Bueno, entonces crea:
mount -o remount,rw /system mkdir /system/etc/init.d chmod 0755 /system/etc/init.d mount -o remount,ro /system
Ahora agregue un script simple allí, por ejemplo:
echo "echo 'Init.d is working !!!' >> /sdcard/init_test.log" > /system/etc/init.d/90my_script chmod 777 /system/etc/init.d/90my_script
Reiniciamos el dispositivo y vemos si ocurrió un milagro ... Desafortunadamente, mi archivo no apareció.
Examinamos el sistema más a fondo y buscamos algún archivo de inicio que pueda ejecutar scripts después del lanzamiento. Tenía un archivo en
/init.rc en mi dispositivo. Bueno, intentemos cambiarlo y reiniciar el dispositivo:
mount -o remount,rw / echo "echo 'Init.d is working !!!' >> /sdcard/init_test.log" >> /init.rc mount -o remount,ro / reboot
Pero el archivo no fue creado nuevamente. Vamos a ver el archivo
/init.rc y nuestro registro desapareció y el archivo no pareció cambiar, porque la fecha de creación es bastante extraña (en mi caso, 1 de enero de 70 05:00:00).
Seguimos entendiendo, y resulta que este archivo está almacenado en
boot.img , y cada vez que sale de él. Y para cambiar la funcionalidad del archivo
init.rc , debe hacer todo
esto .
Pero hay una manera más fácil de ayudar a resolver este problema. Para este método, podemos usar el siguiente script de shell (gracias a Ryuinferno):
Comenzando con el guión! En mi caso, se llamará init.sh.
1. Descargue el archivo en la tarjeta sd del dispositivo móvil:
adb push /tmp/init.sh /sdcard
2. Copie a la memoria del dispositivo móvil y configure los derechos necesarios:
adb shell su cp /sdcard/init.sh /data/init.sh chmod 777 /data/init.sh
3. Ejecutar para ejecución:
/data/init.sh
Y preste atención al registro que se muestra. Aquí está mi registro:
Ejecutar registro Init.d Enabler by Ryuinferno @ XDA Hello Supaa User! :P busybox found! Awesome! grep found! :D Good! run-parts found! :) Great! Let's proceed... Press enter to continue... Mounting system as rewritable... Removing old sysinit file rm: /system/bin/sysinit: No such file or directory Checking for the presence of sysinit in /system/bin... sysinit not found, creating file... Setting correct permissions and ownership for sysinit... Checking for the presence of install-recovery.sh... install-recovery.sh not found, creating it... Setting the correct permissions and ownership for install-recovery.sh... Also for install-recovery-2.sh if it exists... Checking for the presence of the init.d folder... init.d folder found... Creating basic init.d scripts... Creating permissive SELinux script... Setting correct permissions and ownership for init.d folder and scipts... Mounting system as read-only... Done!!! Please reboot at least twice before checking /data... If init.d is working, you will see a Test.log in /data... Enjoy!!! =) Ryuinferno @ XDA 2013
Como puede ver en el registro, no hay errores, ¡así que no dude en reiniciar el dispositivo! Tal vez alguien ya trabajó y podría encontrar el archivo
/data/Test.log , pero no lo tengo. Verifique el directorio
/system/etc/init.d con el
comando ls :
00test 01permissive 08setperm
Como puede ver, las tareas se han creado con éxito. Es posible que aún tenga que cambiar
boot.img , pero veamos al principio dónde está el archivo
install-recovery.sh con el comando
find / -name "install-recovery.sh" ... /system/bin/install-recovery.sh /system/etc/install-recovery.sh ...
Como podemos ver, tenemos 2 archivos que se encuentran en diferentes lugares. En la fecha de creación, podemos notar que el script creó el archivo en el directorio
/system/etc/install-recovery.sh , aunque, tal vez, en algunos casos debería crearlo en
/ system / etc. Cambiemos el nombre del archivo a bin y copiemos el archivo, etc.
mount -o remount,rw /system mv /install-recovery.sh /system/bin/install-recovery2.sh cp /install-recovery.sh /system/bin/
UPD : tenga en cuenta que el contexto de seguridad para ambos archivos debe coincidir. Y si de repente se perdió durante la copia (aunque en teoría esto no debería ser así), deberá restaurarlo (por ejemplo, a través de la utilidad
chcon ). Vea la información completa del archivo con
ls -lZ :
ls -lZ /system/etc/install-recovery.sh
Aquí
u: object_r: system_file: s0 es contextos de seguridad.
Y nuevamente reiniciamos el dispositivo ... ¡Y ahora, finalmente, el ÉXITO tan esperado!
¡Ha aparecido el archivo
/data/Test.log !
Una vez que todo funcione, vaya a
/system/etc/init.d y cree un script de shell. Y en él, simplemente ejecuta nuestro crond para ejecutar:
echo "#!/system/bin/sh crond -b -L /sdcard/error.log -c /data/crontab" > /system/etc/init.d/99cronstart chmod 777 /system/etc/init.d/99cronstart reboot
Después de la descarga, verifique si crond ha comenzado:
ps | grep crond root 414 1 9532 236 hrtimer_na 000dcf90 S crond
Y podríamos terminar ahora, pero esperemos un minuto y veamos si había un registro en nuestro archivo ... Bueno, como ya entendieron, nuevamente, nada funcionó. El hecho es que este proceso debe ejecutarse desde un superusuario. Cambie el script en el archivo
99cronstart :
echo "#!/system/bin/sh /su/bin/su -c crond -b -L /sdcard/error.log -c /data/crontab" > /system/etc/init.d/99cronstart reboot
UPD : Quizás en su caso
su tenga una ruta diferente, luego use el comando
que su y reemplace la ruta con la suya.
¡Ahora nuestro dispositivo Android admite tareas cron y puede contener scripts de shell para el inicio automático!
Y finalmente, el script que ejecutará nuestra aplicación, si no está en los procesos y guardará información sobre lo que estaba en la pantalla principal antes de iniciar nuestra aplicación:
proc=$(ps | grep "com.test.app") if [ "$proc" == "" ]; then dumpsys window | grep CurrentFocus > /sdcard/current_focus.dump sleep 1 am start -n com.test.app/com.test.app.activities.MainActivity fi