Bekerja dengan cron untuk Android dan menambahkan skrip shell ke autorun saat perangkat melakukan booting



Karena perangkat seluler telah lama memiliki fungsionalitas yang luas, tugas otomasi dapat dengan mudah ditransfer ke sana. Dan, sebaik mungkin, cron sama baiknya untuk mengeksekusi mereka. Tetapi jika cron membutuhkan sedikit waktu dalam sistem Linux "biasa", maka perangkat Android membutuhkan pekerjaan yang lebih rumit untuk mengkonfigurasinya.

Jika Anda tertarik pada topik otomatisasi dan Anda ingin skrip shell Anda diluncurkan segera setelah perangkat dinyalakan, dan bahkan dapat dimulai dengan timer - selamat datang di kucing!

Kata Pengantar


Saya terlibat dalam otomatisasi perangkat seluler untuk Android. Dan selama eksekusi skrip otomatis, banyak situasi tak terduga terjadi, bahkan jika perangkat yang sama digunakan untuk pengujian.

Masalah paling populer:

0. Skrip otomatisasi tidak melakukan apa yang Anda inginkan.
1. Aplikasi seluler diunduh secara otomatis
2. Reboot telepon otomatis
3. Aplikasi seluler tidak secara otomatis memulai setelah restart
4. Modul Wi-Fi mati secara acak, tidak menemukan jaringan, tidak terhubung ke jaringan
5. Jaringan seluler tiba-tiba menghilang
6. Telepon masuk ke mode tidur
7. Proxy terjatuh atau server itu sendiri atau server mengembalikan respons aneh

Karena itu, Anda harus terus-menerus memonitor perangkat dan menangkap situasi yang tidak terduga ini.



Jadi, saya sampai pada kesimpulan bahwa cron dengan skrip "benar" akan memungkinkan Anda untuk melacak kegagalan perangkat lunak dan mengembalikan skrip otomatisasi atau menjalankannya lagi. Tapi ternyata, meskipun Android mengandung kernel Linux, ada nuansa khusus yang harus saya tangani. Jadi mari kita mulai menyiapkan!

Penyiapan cron


Sesuaikan lingkungan


  1. Instal adb untuk mengakses perangkat melalui shell menggunakan kabel usb.
  2. Kami membuka bagian Untuk pengembang . Untuk melakukan ini, buka bagian Tentang telepon dan buat beberapa klik pada nomor Build atau yang serupa.
  3. Kami pergi ke bagian Untuk pengembang dan menyalakannya. Kami menghubungkan perangkat ke komputer dan memungkinkan akses di komputer ini ke perangkat ini.
  4. Tambahkan root untuk perangkat Anda. Opsi yang paling umum adalah SuperSu , Magisk, dan Kingroot . Pergi ke w3bsit3-dns.com dan temukan opsi root untuk perangkat Anda. Sayangnya, tidak ada root universal.
  5. Kami menginstal BusyBox (itu juga di w3bsit3-dns.com, misalnya), karena hanya berisi program cron.

Pengaturan mulai manual


  1. Kami terhubung ke ponsel menggunakan adb shell (jika adb tidak terdaftar dalam variabel lingkungan Anda, kemudian tambahkan path lengkap.
  2. Pergi ke mode root dengan perintah su
  3. Kami memeriksa keberadaan program cron dan melihat pengaturan menggunakan perintah crond -h

hasil eksekusi
crond: 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 


Seperti yang ditunjukkan baris terakhir, instruksi default harus disimpan di direktori / var / spool / cron / crontab , yang tidak secara otomatis dibuat dan jika kita menjalankan perintah
 crond -b 
dan kemudian periksa apakah proses dimulai
 ps | grep crond 
, maka mungkin tidak ada di sana, karena dia tidak bisa mendapatkan instruksi apa pun. Jadi mari kita jalankan perintah
 crond -b -fd0 
dan lihat apa alasannya. Kemungkinan besar Anda akan memiliki kesalahan yang sama:
crond: can't change directory to '/var/spool/cron/crontabs': No such file or directory . Dalam hal ini, ini normal, karena di masa depan, kami sendiri akan menunjukkan jalur ke file executable crontab.

4. Buat file crontab sederhana:

 mkdir /data/crontab echo "*/1 * * * * echo 'text' >> /sdcard/test.txt" > /data/crontab/root 

Sekarang kami memiliki tugas yang setiap menit akan menambahkan teks kata ke file /sdcard/test.txt
Kami meluncurkan:
 crond -b -fd0 -c /data/crontab 
dan dapatkan log berikut:

 crond: crond (busybox 1.29.2-Stericson) started, log level 0 crond: ignoring file 'root' (no such user) ... 

Tentu saja, ini sedikit mengejutkan, karena jika kita menjalankan perintah whoami, itu akan mengembalikan root sebagai hasilnya.

5. Tambahkan pengguna root, karena crond bertanya:

 mount -o remount,rw /system; echo "root:x:0:0::/system/etc/crontabs:/system/bin/sh" >> /system/etc/passwd; mount -o remount,ro /system; 

Karena kurangnya file ini, saya menyadari bahwa dalam sistem Android tidak terlibat sama sekali. Jika Anda yakin di mana Anda akan menyimpan file crontab Anda, maka Anda dapat mengganti baris / sistem / etc / crontab dengan yang Anda butuhkan. Jalankan perintah lagi

 crond -b -fd0 -c /data/crontab 

Dan kami mendapatkan yang berikut:

 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 

Meskipun, menurut log, tugas itu terdaftar di crond, tetapi dalam kasus saya file tersebut tidak dibuat. Masalahnya dapat diselesaikan dengan sangat sederhana:

 mkdir -p /system/etc/crontabs 

Yah, dia ingin direktori ada di sana, siapa kita untuk melarangnya! Kami mulai lagi dan melihat:

 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 

Kesalahan hilang dan baris crond: child running / system / bin / sh muncul . Akhirnya, cron telah berhasil diselesaikan, dan Anda dapat melanjutkan ke bagian kedua!

Unduh skrip shell otomatis


Sistem Linux memiliki direktori init.d yang bertanggung jawab untuk autostart segera setelah sistem melakukan booting, jadi mari kita coba cara ini!

1. Periksa apakah direktori ini ada di perangkat Anda (ini adalah /etc/init.d atau /system/etc/init.d - ini adalah partisi yang sama, dll). Dalam kasus saya, tidak. Nah, lalu buat:

 mount -o remount,rw /system mkdir /system/etc/init.d chmod 0755 /system/etc/init.d mount -o remount,ro /system 

Sekarang tambahkan beberapa skrip sederhana di sana, misalnya:

 echo "echo 'Init.d is working !!!' >> /sdcard/init_test.log" > /system/etc/init.d/90my_script chmod 777 /system/etc/init.d/90my_script 

Kami me-reboot perangkat dan melihat apakah keajaiban terjadi ... Sayangnya, file saya tidak muncul.

Kami memeriksa sistem lebih lanjut dan mencari beberapa file init yang dapat menjalankan skrip setelah diluncurkan. Saya punya file di /init.rc di perangkat saya. Baiklah, mari kita coba ubah dan reboot perangkat:

 mount -o remount,rw / echo "echo 'Init.d is working !!!' >> /sdcard/init_test.log" >> /init.rc mount -o remount,ro / reboot 

Tetapi file itu tidak dibuat lagi. Kami pergi untuk melihat file /init.rc dan catatan kami menghilang dan file sepertinya tidak berubah, karena tanggal pembuatannya cukup aneh (dalam kasus saya, 1 Januari, 70 05:00).

Kami terus memahami, dan ternyata file ini disimpan di boot.img , dan setiap kali ia keluar darinya. Dan untuk mengubah fungsionalitas file init.rc , Anda harus melakukan semua ini .

Tetapi ada cara yang lebih mudah untuk membantu menyelesaikan masalah ini. Untuk metode ini, kita dapat menggunakan skrip shell berikut (ucapkan terima kasih kepada Ryuinferno):

Skrip shell
 #!/system/bin/sh #Script to enable init.d by Ryuinferno @ XDA error_msg(){ echo "You do not need this mod..." sleep 1 echo "If you are reapplying, please delete these files if present:" echo "/system/bin/sysinit" sleep 1 echo "/system/etc/install-recovery.sh" sleep 1 echo "/system/etc/install-recovery-2.sh" sleep 1 echo "And run again..." sleep 1 echo "If init.d is still not working, read the FAQ part in my thread..." sleep 1 echo "Aborting..." mount -o remount,ro -t auto /system echo "" echo "Ryuinferno @ XDA" exit 1 } echo "Init.d Enabler by Ryuinferno @ XDA" echo "" sleep 1 id=`id`; id=`echo ${id#*=}`; id=`echo ${id%%\(*}`; id=`echo ${id%% *}` if [ "$id" != "0" ] && [ "$id" != "root" ]; then echo "Script NOT running as root!" sleep 1 echo "Superuser access not granted!" sleep 1 echo "Please type 'su' first before running this script..." exit 1 else echo "Hello Supaa User! :P" echo "" sleep 1 fi if [ ! "'which busybox'" ]; then echo "busybox NOT INSTALLED!" sleep 1 echo "Please install busybox first!" exit 1 else echo "busybox found!" sleep 1 fi bbb=0 if [ ! "`which grep`" ]; then bbb=1 echo "grep applet NOT FOUND!" sleep 1 else echo "Awesome! grep found! :D" sleep 1 fi if [ ! "`which run-parts`" ]; then bbb=1 echo "run-parts applet NOT FOUND!" sleep 1 else echo "Good! run-parts found! :)" echo "" sleep 1 fi if [ $bbb -eq 1 ] ; then echo "" echo "Required applets are NOT FOUND!" echo "" sleep 1 echo "Please reinstall busybox!" exit 1 fi echo "Great! Let's proceed..." echo "" sleep 1 echo "Press enter to continue..." read enterKey clear sleep 1 echo "Mounting system as rewritable..." mount -o remount,rw -t auto /system sleep 1 echo "Removing old sysinit file" rm /system/bin/sysinit sleep 1 echo "" echo "Checking for the presence of sysinit in /system/bin..." sleep 1 if [ -e /system/bin/sysinit ]; then echo "sysinit found..." if [ -z "`cat /system/bin/sysinit | grep "init.d"`" ]; then echo "Adding lines to sysinit..." echo "" >> /system/bin/sysinit echo "# init.d support" >> /system/bin/sysinit echo "" >> /system/bin/sysinit echo "export PATH=/sbin:/system/sbin:/system/bin:/system/xbin" >> /system/bin/sysinit echo "run-parts /system/etc/init.d" >> /system/bin/sysinit echo "" >> /system/bin/sysinit else echo "" echo "Your sysinit should already be running the scripts in init.d folder at boot..." error_msg fi else echo "sysinit not found, creating file..." echo "#!/system/bin/sh" > /system/bin/sysinit echo "# init.d support" >> /system/bin/sysinit echo "" >> /system/bin/sysinit echo "export PATH=/sbin:/system/sbin:/system/bin:/system/xbin" >> /system/bin/sysinit echo "run-parts /system/etc/init.d" >> /system/bin/sysinit echo "" >> /system/bin/sysinit fi sleep 1 echo "Setting correct permissions and ownership for sysinit..." chmod 755 /system/bin/sysinit chown 0.2000 /system/bin/sysinit sleep 1 echo "" echo "Checking for the presence of install-recovery.sh..." sleep 1 if [ -f /system/etc/install-recovery.sh ] && [ -z "`cat /system/etc/install-recovery.sh | grep "daemon"`" ]; then if [ ! -z "`cat /system/etc/install-recovery.sh | grep "init.d"`" ];then echo "Your install-recovery.sh seems to be already modified for init.d..." error_msg fi echo "install-recovery.sh found, renaming it as install-recovery-2.sh..." mv /system/etc/install-recovery.sh /system/etc/install-recovery-2.sh echo "Recreating install-recovery.sh..." echo "#!/system/bin/sh" > /system/etc/install-recovery.sh echo "# init.d support" >> /system/etc/install-recovery.sh echo "" >> /system/etc/install-recovery.sh echo "/system/bin/sysinit" >> /system/etc/install-recovery.sh echo "" >> /system/etc/install-recovery.sh echo "# excecuting extra commands" >> /system/etc/install-recovery.sh echo "/system/etc/install-recovery-2.sh" >> /system/etc/install-recovery.sh echo "" >> /system/etc/install-recovery.sh elif [ -f /system/etc/install-recovery.sh ] && [ ! -z "`cat /system/etc/install-recovery.sh | grep "daemon"`" ]; then if [ -f /system/etc/install-recovery-2.sh ] && [ ! -z "`cat /system/etc/install-recovery-2.sh | grep "init.d"`" ];then echo "Your install-recovery-2.sh seems to be already modified for init.d..." error_msg fi echo "install-recovery.sh is used for superuser, using install-recovery-2.sh instead..." if [ -f /system/etc/install-recovery-2.sh ]; then echo "" >> /system/etc/install-recovery-2.sh echo "# init.d support" >> /system/etc/install-recovery-2.sh echo "/system/bin/sysinit" >> /system/etc/install-recovery-2.sh echo "" >> /system/etc/install-recovery-2.sh else echo "#!/system/bin/sh" > /system/etc/install-recovery-2.sh echo "# init.d support" >> /system/etc/install-recovery-2.sh echo "" >> /system/etc/install-recovery-2.sh echo "/system/bin/sysinit" >> /system/etc/install-recovery-2.sh echo "" >> /system/etc/install-recovery-2.sh fi if [ -z "`cat /system/etc/install-recovery.sh | grep "install-recovery-2.sh"`" ]; then echo "" >> /system/etc/install-recovery.sh echo "# extra commands" >> /system/etc/install-recovery.sh echo "/system/etc/install-recovery-2.sh" >> /system/etc/install-recovery.sh echo "" >> /system/etc/install-recovery.sh fi else echo "install-recovery.sh not found, creating it..." echo "#!/system/bin/sh" > /system/etc/install-recovery.sh echo "# init.d support" >> /system/etc/install-recovery.sh echo "" >> /system/etc/install-recovery.sh echo "/system/bin/sysinit" >> /system/etc/install-recovery.sh echo "" >> /system/etc/install-recovery.sh fi sleep 1 echo "Setting the correct permissions and ownership for install-recovery.sh..." echo "Also for install-recovery-2.sh if it exists..." chmod 755 /system/etc/install-recovery.sh chown 0.0 /system/etc/install-recovery.sh if [ -f /system/etc/install-recovery-2.sh ]; then chmod 755 /system/etc/install-recovery-2.sh chown 0.0 /system/etc/install-recovery-2.sh fi sleep 1 echo "" echo "Checking for the presence of the init.d folder..." sleep 1 if [ -d /system/etc/init.d ]; then echo "init.d folder found..." else echo "init.d folder not found, creating the folder..." mkdir /system/etc/init.d fi sleep 1 echo "" echo "Creating basic init.d scripts..." echo "#!/system/bin/sh" > /system/etc/init.d/08setperm echo "#set correct permissions to /system/etc/init.d folder" >> /system/etc/init.d/08setperm echo "" >> /system/etc/init.d/08setperm echo "mount -o remount,rw -t auto /system" >> /system/etc/init.d/08setperm echo "chmod -R 777 /system/etc/init.d" >> /system/etc/init.d/08setperm echo "mount -o remount,ro -t auto /system" >> /system/etc/init.d/08setperm echo "" >> /system/etc/init.d/08setperm echo "#!/system/bin/sh" > /system/etc/init.d/00test echo "#init.d test" >> /system/etc/init.d/00test echo "" >> /system/etc/init.d/00test echo "if [ -f /data/Test.log ]; then" >> /system/etc/init.d/00test echo "rm /data/Test.log" >> /system/etc/init.d/00test echo "fi" >> /system/etc/init.d/00test echo "" >> /system/etc/init.d/00test echo 'echo "Init.d is working !!!" >> /data/Test.log' >> /system/etc/init.d/00test echo 'echo "excecuted on $(date +"%d-%m-%Y %r" )" >> /data/Test.log' >> /system/etc/init.d/00test echo "" >> /system/etc/init.d/00test sleep 1 echo "Creating permissive SELinux script..." sleep 1 echo "#!/system/bin/sh" >> /system/etc/init.d/01permissive echo "#Init.d Permissive SELinux" >> /system/etc/init.d/01permissive echo "" >> /system/etc/init.d/01permissive echo "busybox mount -o remount,rw -t auto /system" >> /system/etc/init.d/01permissive echo "" >> /system/etc/init.d/01permissive echo "setenforce 0" >> /system/etc/init.d/01permissive echo "SELINUX=permissive" >> /system/etc/init.d/01permissive echo "" >> /system/etc/init.d/01permissive sleep 1 echo "Setting correct permissions and ownership for init.d folder and scipts..." chmod 777 /system/etc/init.d chmod 777 /system/etc/init.d/08setperm chmod 777 /system/etc/init.d/00test chmod 777 /system/etc/init.d/01permissive chown 0.0 /system/etc/init.d chown 0.0 /system/etc/init.d/08setperm chown 0.0 /system/etc/init.d/00test chown 0.0 /system/etc/init.d/01permissive sleep 1 echo "" echo "Mounting system as read-only..." mount -o remount,ro -t auto /system sleep 1 echo "" echo "Done!!!" sleep 1 echo "Please reboot at least twice before checking /data..." sleep 1 echo "If init.d is working, you will see a Test.log in /data..." sleep 1 echo "" echo "Enjoy!!! =)" echo "Ryuinferno @ XDA 2013" exit 


Memulai dengan skrip! Dalam kasus saya, itu akan disebut init.sh.
1. Unduh file ke sdcard perangkat seluler:
 adb push /tmp/init.sh /sdcard 

2. Salin ke memori perangkat seluler dan tetapkan hak yang diperlukan:
 adb shell su cp /sdcard/init.sh /data/init.sh chmod 777 /data/init.sh 

3. Jalankan untuk eksekusi:
 /data/init.sh 

Dan perhatikan log yang ditampilkan. Ini log saya:
Jalankan log
 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 


Seperti yang dapat Anda lihat dari log, tidak ada kesalahan, jadi silakan reboot perangkat! Mungkin seseorang sudah bekerja dan Anda dapat menemukan file / data / Test.log , tetapi saya tidak memilikinya. Periksa direktori /system/etc/init.d menggunakan perintah ls :

 00test 01permissive 08setperm 

Seperti yang Anda lihat, tugas telah berhasil dibuat. Anda mungkin masih harus mengubah boot.img , tetapi mari kita periksa di awal, di mana file install-recovery.sh dengan perintah

 find / -name "install-recovery.sh" ... /system/bin/install-recovery.sh /system/etc/install-recovery.sh ... 

Seperti yang dapat kita lihat, kita memiliki 2 file yang terletak di tempat yang berbeda. Pada tanggal pembuatan, kita dapat melihat bahwa skrip tersebut membuat file di direktori /system/etc/install-recovery.sh , walaupun, dalam beberapa kasus, ia harus membuatnya di / system / dll. Mari ganti nama file menjadi bin dan salin file dari dll:

 mount -o remount,rw /system mv /install-recovery.sh /system/bin/install-recovery2.sh cp /install-recovery.sh /system/bin/ 


UPD : Harap perhatikan bahwa konteks keamanan untuk kedua file harus cocok. Dan jika Anda tiba-tiba tersesat saat menyalin (walaupun secara teori ini seharusnya tidak), Anda harus mengembalikannya (misalnya, melalui utilitas chcon ). Lihat informasi file lengkap dengan ls -lZ :
 ls -lZ /system/etc/install-recovery.sh # -rwxr-xr-x root root u:object_r:system_file:s0 install-recovery.sh 

Di sini u: object_r: system_file: s0 adalah konteks keamanan.

Dan lagi kita me-reboot perangkat ... Dan sekarang, akhirnya, SUKSES yang telah lama ditunggu-tunggu! File /data/Test.log telah muncul!

Setelah semuanya berfungsi, buka /system/etc/init.d dan buat skrip shell. Dan di dalamnya, jalankan perintah kami untuk menjalankan:

 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 

Setelah mengunduh, periksa apakah crond sudah mulai:

 ps | grep crond root 414 1 9532 236 hrtimer_na 000dcf90 S crond 

Dan kita bisa mengakhiri sekarang, tapi mari kita tunggu sebentar dan lihat apakah ada catatan di file kita ... Nah, seperti yang sudah Anda pahami, sekali lagi, tidak ada yang berhasil. Faktanya adalah bahwa proses ini perlu dijalankan dari pengguna super. Ubah skrip dalam file 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 : Mungkin dalam kasus Anda su akan memiliki jalur yang berbeda, kemudian gunakan perintah yang su dan ganti jalur dengan Anda.

Sekarang perangkat Android kami mendukung tugas cron dan mungkin berisi skrip shell untuk peluncuran otomatis!

Dan akhirnya, skrip yang akan menjalankan aplikasi kita jika tidak dalam proses dan menyimpan informasi tentang apa yang ada di layar utama sebelum meluncurkan aplikasi kita:

 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 

Source: https://habr.com/ru/post/id468337/


All Articles