
由于移动设备长期以来具有广泛的功能,因此可以轻松地将自动化任务转移给它们。 而且,cron尽可能地适合执行它们。 但是,如果cron在“普通” Linux系统上花费一些时间,则Android设备需要进行更复杂的配置工作。
如果您对自动化主题感兴趣,并且希望在设备启动后立即启动Shell脚本,甚至可以通过计时器启动,那么欢迎您!
前言
我从事Android移动设备的自动化。 在执行自动脚本的过程中,即使使用相同的设备进行测试,也会发生许多无法预料的情况。
最受欢迎的问题:
0.自动化脚本无法满足您的需求。
1.移动应用程序自动下载
2.手机自动重启
3.重新启动后,移动应用程序不会自动启动
4. Wi-Fi模块随机关闭,找不到网络,未连接到网络
5.移动网络突然消失
6.手机进入睡眠模式
7.代理掉线或服务器本身或服务器返回奇怪的响应
因此,您必须不断监视设备并捕获这些不可预见的情况。

因此,我得出的结论是,带有“正确”脚本的cron将使您能够跟踪软件故障并还原自动化脚本或再次运行它。 但事实证明,尽管Android包含Linux内核,但我必须处理一些特殊的细微差别。 因此,让我们开始进行设置!
Cron设置
定制环境
- 安装adb以使用USB线通过外壳访问设备。
- 我们打开“面向开发人员 ”部分。 为此,请转到“ 关于电话”部分,然后单击“ 内部版本号”或类似名称。
- 我们转到面向开发人员的部分,然后将其打开。 我们将设备连接到计算机,并允许在此计算机上访问该设备。
- 为您的设备添加root 。 最常见的选项是SuperSu , Magisk和Kingroot 。 转到w3bsit3-dns.com并找到您设备的root选项。 不幸的是,没有普遍的根源。
- 我们安装了BusyBox (例如,它也在w3bsit3-dns.com上),因为它仅包含一个cron程序。
手动开始设定
- 我们使用adb shell连接到电话(如果adb未在您的环境变量中注册,请添加完整路径。
- 使用su命令进入root模式
- 我们检查cron程序是否存在,并使用crond -h命令查看设置
执行结果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
从最后一行可以看到,默认指令应存储在目录
/ var / spool / cron / crontabs中 ,该目录不会自动创建,并且如果我们运行命令
crond -b
然后检查该过程是否开始
ps | grep crond
,那么它可能不存在,因为 他没有得到任何指示。 所以我们执行命令
crond -b -fd0
看看是什么原因。 您很可能会遇到类似的错误:
crond: can't change directory to '/var/spool/cron/crontabs': No such file or directory
。 在这种情况下,这是正常的,因为 将来,我们自己将指示crontab可执行文件的路径。
4.创建一个简单的crontab文件:
mkdir /data/crontab echo "*/1 * * * * echo 'text' >> /sdcard/test.txt" > /data/crontab/root
现在我们有一个任务,每分钟将单词
文本添加到文件
/sdcard/test.txt中我们推出:
crond -b -fd0 -c /data/crontab
并获得以下日志:
crond: crond (busybox 1.29.2-Stericson) started, log level 0 crond: ignoring file 'root' (no such user) ...
当然,这有点令人惊讶,因为如果我们执行
whoami命令,它将作为结果返回
root 。
5.添加root用户,因为crond会询问:
mount -o remount,rw /system; echo "root:x:0:0::/system/etc/crontabs:/system/bin/sh" >> /system/etc/passwd; mount -o remount,ro /system;
由于缺少此文件,我意识到在Android系统中根本不涉及该文件。 如果您确定将crontab文件存储在何处,则可以用所需的行替换
/ system / etc / crontabs 。 再次运行命令
crond -b -fd0 -c /data/crontab
我们得到以下信息:
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
尽管根据日志,该任务已在crond中注册,但是在我的情况下,未创建文件。 这个问题可以很简单地解决:
mkdir -p /system/etc/crontabs
好吧,他想要一个目录存在于此,我们该禁止他! 我们再次开始,看到:
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
错误消失了,并出现了以下问题
:子运行中/ system / bin / sh 。 最后,cron已成功结束,您可以继续进行第二部分!
自动shell脚本下载
Linux系统有一个
init.d目录,该目录负责在系统引导后立即自动启动,所以让我们尝试一下!
1.检查此目录在您的设备上是否存在(这是
/etc/init.d或
/system/etc/init.d-这是相同的已安装分区等)。 就我而言,事实并非如此。 好吧,然后创建:
mount -o remount,rw /system mkdir /system/etc/init.d chmod 0755 /system/etc/init.d mount -o remount,ro /system
现在在其中添加一些简单的脚本,例如:
echo "echo 'Init.d is working !!!' >> /sdcard/init_test.log" > /system/etc/init.d/90my_script chmod 777 /system/etc/init.d/90my_script
我们重新启动设备,看看是否发生了奇迹...不幸的是,我的文件没有出现。
我们将进一步检查系统,并寻找一些可以在启动后运行脚本的初始化文件。 我的设备上的
/init.rc中有一个文件。 好吧,让我们尝试更改它并重新启动设备:
mount -o remount,rw / echo "echo 'Init.d is working !!!' >> /sdcard/init_test.log" >> /init.rc mount -o remount,ro / reboot
但是没有再次创建该文件。 我们去查看文件
/init.rc ,我们的记录消失了,文件似乎没有变化,因为 创建日期非常奇怪(以我为例,70年1月1日,05:00:00)。
我们继续理解,事实证明该文件存储在
boot.img中 ,并且每次退出该文件时都会存储。 为了更改
init.rc文件的功能,
您需要做所有
这一切。
但是,有一种更简单的方法可以帮助解决此问题。 对于这种方法,我们可以使用以下shell脚本(感谢Ryuinferno):
脚本入门! 在我的情况下,它将称为init.sh。
1.将文件下载到移动设备的SD卡中:
adb push /tmp/init.sh /sdcard
2.复制到移动设备的内存中并设置必要的权限:
adb shell su cp /sdcard/init.sh /data/init.sh chmod 777 /data/init.sh
3.运行执行:
/data/init.sh
并注意显示的日志。 这是我的日志:
运行日志 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
从日志中可以看到,没有错误,请随时重新启动设备! 也许有人已经在工作,您可以找到
/data/Test.log文件,但我没有。 使用
ls命令检查
/system/etc/init.d目录:
00test 01permissive 08setperm
如您所见,任务已成功创建。 您可能仍然需要更改
boot.img ,但是让我们在开始时检查一下,其中的
install-recovery.sh文件在以下位置:
find / -name "install-recovery.sh" ... /system/bin/install-recovery.sh /system/etc/install-recovery.sh ...
如我们所见,我们有2个文件位于不同的位置。 在创建日期之前,我们可以注意到该脚本在
/system/etc/install-recovery.sh目录中创建了该文件,尽管在某些情况下,它应该在
/ system / etc中创建该文件
。 让我们将文件重命名为bin并从etc复制文件:
mount -o remount,rw /system mv /install-recovery.sh /system/bin/install-recovery2.sh cp /install-recovery.sh /system/bin/
UPD :请注意,两个文件的安全性上下文必须匹配。 而且,如果您在复制时突然迷路(虽然从理论上讲应该不是),则需要将其还原(例如,通过
chcon实用程序)。 使用
ls -lZ查看完整的文件信息:
ls -lZ /system/etc/install-recovery.sh
在这里
u:object_r:system_file:s0是安全上下文。
再次,我们重新启动设备...现在,终于,期待已久的成功! 文件
/data/Test.log已经出现!
一切正常后,转到
/system/etc/init.d并创建一个shell脚本。 然后在其中运行我们的crond以执行:
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
下载后,检查crond是否已启动:
ps | grep crond root 414 1 9532 236 hrtimer_na 000dcf90 S crond
现在可以结束了,但是让我们等待一分钟,看看我们的文件中是否有记录...好了,正如您已经了解的那样,什么也没起作用。 事实是,此过程需要从超级用户运行。 更改
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 :也许在您的情况下,
su将具有不同的路径,然后使用
su命令并用您的路径替换该路径。
现在,我们的Android设备支持cron任务,并且可能包含用于自动启动的shell脚本!
最后,将运行我们的应用程序的脚本(如果不在进程中)并在启动我们的应用程序之前保存有关主屏幕上内容的信息:
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