How to use crontab in Android?

后端 未结 4 797
你的背包
你的背包 2020-12-13 06:59

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, a

相关标签:
4条回答
  • 2020-12-13 07:29

    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

    0 讨论(0)
  • 2020-12-13 07:42

    Requirements

    1. Root access: for superuser commads like reboot, or init.d config. Crond can still run under normal user privs.

    2. Busybox: for 'crond' service

    3. (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.

    1. If the crond is not obeying your timezone, you might need to update the tzdata in your device.

    2. Better to test with */1 * * * * to see if it is working.

    0 讨论(0)
  • 2020-12-13 07:45

    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
    
    0 讨论(0)
  • 2020-12-13 07:46

    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.

    0 讨论(0)
提交回复
热议问题