'How to use crontab in Android?
I can't find answer to my question: Is it possible to run crontab
to reboot Android using busybox
(or other means)
Tried to run crontab, and it complain about unknown uid 0.
Tried to run reboot, and it does nothing.
Or I am asking for the impossible right now?
Solution 1:[1]
Requirements
Root access: for superuser commads like reboot, or init.d config. Crond can still run under normal user privs.
Busybox: for 'crond' service
(Optional) init.d support: to start 'crond' service at boot. Or start via Magisk post-fs-data.d script.
Creating cronjob
Create the cronjob file in directory /data/crontab/ (it could be any accessible directory even in sdcard) with filename 'root'. Write your cronjob inside the file 'root'.
echo '
53 * * * * reboot' >> /data/crontab/root
Test without rebooting
Now open any terminal emulator in device and run the following commands..
su -
crond -b -c /data/crontab
Now the crond service will start, to check type pgrep -l crond
or ps | grep crond
Start crond at boot
create a file at /system/etc/init.d with executable permission:
echo '
crond -b -c /data/crontab' > /system/etc/init.d/crond
chmod +x /system/etc/init.d/crond
Example cronjobs
53 * * * * reboot
Will reboot your device on 53rd minute of every hour.
Note: 1. If you modify crontab, remember to restart crond daemon after killing the existing one.
If the crond is not obeying your timezone, you might need to update the tzdata in your device.
Better to test with */1 * * * * to see if it is working.
Solution 2:[2]
This is a complement to Seff's answer above. Couldn't place it in a comment because it's too long
/system/etc/init.d
is not always guaranteed to work. In my case it did not. There are other methods mentioned in the following link in case this one didn't work for you https://android.stackexchange.com/questions/6558/how-can-i-run-a-script-on-boot/196785
Even then crond didn't run any job for me.
To debug the errors I killed the running instance pkill crond
and ran it like that
crond -f -d0 -c /data/crontab/
This make crond run in forground and print all the debugging information. When I ran it like that I got this warning
crond: crond (busybox 1.27.2-Stericson) started, log level 0
crond: ignoring file 'root' (no such user)
So I had to create a passwd file with entry for root
echo 'root:x:0:0:root:/data:/system/bin/sh' > /system/etc/passwd
Even then, it still failed with error like
crond: job: 0 /system/bin/ls
crond: child running /bin/sh
crond: can't execute '/bin/sh' for user root
Please note that no where in my cronjob did I mentioned "/bin/sh". This seems to be hard coded in the binary.
Next I added the following lines to my init script
/system/xbin/mount -o remount,rw /
/system/xbin/ln -s /system/bin/ /bin
/system/xbin/mount -o remount,ro /
and that's it. It worked fine after that
Solution 3:[3]
if you get error "read only file system", you need to remount the /system as read-write:
mount -o rw,remount /dev/stl12 /system
When done, remount it as read-only:
mount -o ro,remount /dev/stl12 /system
Solution 4:[4]
You will likely need to set your TimeZone and add a root user. Adding a root user can be done like this:
echo "root:x:0:0::/system/etc/crontabs:/system/bin/sh" > /system/etc/passwd
Getting the right TimeZone string is odd. Set the TZ environment variable to the timezone string and make sure crond gets it. I have it under control of a GUI environment, and use the following for getting the TimeZone (may not be correct as I've not tested it on other timezones yet).
public static String findTZS() {
String date = ZooGate.readShellCommand("date");
String[] elements = date.split(" ");
String label = elements[4];
TimeZone tz = Calendar.getInstance().getTimeZone();
boolean dlt = tz.useDaylightTime();
int offset = tz.getDSTSavings()/600000;
DateFormatSymbols dfs = DateFormatSymbols.getInstance();
String[][] z = dfs.getZoneStrings();
for (String[] za: z) {
if (dlt) {
if (za[4].equals(label)) {
return za[2] + offset + za[4];
} else if (za[2].equals(label)) {
return za[2] + offset + za[4];
}
}
}
return "UTC";
}
Also be sure your crontab is named for the user (root) and also owned by that user. If you set the crontab on your internal storage so that you can edit it with Android text editors, you can make it a symlink to /data/media/0. I use /system/etc/crontabs/root -> /data/media/0/Cron/master
You use /data/media and /storage or /sdcard because the latter is a FUSE filesystem that hides the underlying Unix file system permissions and ownership, so you need to set the ownership on the real filesystem in /data.
If you have an older Android that uses Fat or YAFFS or whatever for the internal storage then you might have to keep your crontabs in /system
Beware that cron doesn't always run on time under Android since it likes to oversleep.
Solution 5:[5]
This app works quite well:
https://f-droid.org/packages/it.faerb.crond/
The cron format is the "user" format not the "system" format and all users run as root.
This is how I do a daily reboot of my LineageOS 18.1 Android install:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
1 11 * * * /system/bin/reboot
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | peer |
Solution 2 | Ramast |
Solution 3 | DontVoteMeDown |
Solution 4 | Evan Langlois |
Solution 5 | KJ7LNW |