如何在 Android 中使用 crontab?

Posted

技术标签:

【中文标题】如何在 Android 中使用 crontab?【英文标题】:How to use crontab in Android? 【发布时间】:2013-05-20 19:36:36 【问题描述】:

我找不到问题的答案:是否可以运行 crontab 以使用 busybox(或其他方式)重新启动 android

尝试运行 crontab,但它抱怨未知 uid 0。

尝试重新启动,但它什么也没做。

或者我现在要求的是不可能的事?

【问题讨论】:

***.com/questions/13063106/… 【参考方案1】:

要求

    root 访问权限:用于超级用户命令,如重启或 init.d 配置。 Crond 仍然可以在普通用户权限下运行。

    Busybox:用于“crond”服务

    (可选)init.d 支持:在引导时启动“crond”服务。或者通过 Magisk post-fs-data.d 脚本开始。

创建 cronjob

在目录 /data/crontab/ 中创建 cronjob 文件(即使在 sdcard 中也可以是任何可访问的目录),文件名为“root”。 将您的 cronjob 写入文件“root”中。

echo ' 
53 * * * * reboot' >> /data/crontab/root

无需重启即可测试

现在打开设备中的任何终端模拟器并运行以下命令..

su -
crond -b -c /data/crontab

现在 crond 服务将启动,检查类型 pgrep -l crondps | grep crond

启动时启动 crond

在 /system/etc/init.d 创建一个具有可执行权限的文件:

echo '   
crond -b -c /data/crontab' > /system/etc/init.d/crond

chmod +x /system/etc/init.d/crond

cronjobs 示例

53 * * * * 重启

将在每小时的第 53 分钟重新启动您的设备。

注意: 1.如果修改了crontab,记得杀掉已有的crond守护进程后重启。

    如果 crond 不遵守您的时区,您可能需要更新设备中的 tzdata。

    最好用 */1 * * * * 进行测试,看看它是否工作正常。

【讨论】:

Start crond at boot 部分命令不应该是crond -b -c /data/crond 而是crond -b -c /data/cronjob /system 对我来说是一个只读文件系统,所以我不得不用mount -o rw,remount /systemmount -o ro,remount /system/system/etc/init.d/crond 的创建附上我还在chmod +x 上得到了bad mode,所以我不得不改用chmod 766【参考方案2】:

如果出现“只读文件系统”错误,则需要重新挂载 /system 为可读写:

mount -o rw,remount /dev/stl12 /system

完成后,将其重新安装为只读:

mount -o ro,remount /dev/stl12 /system

【讨论】:

【参考方案3】:

您可能需要设置 TimeZone 并添加 root 用户。添加 root 用户可以这样完成:

echo "root:x:0:0::/system/etc/crontabs:/system/bin/sh" > /system/etc/passwd

获取正确的 TimeZone 字符串很奇怪。将 TZ 环境变量设置为时区字符串,并确保 crond 得到它。我将它置于 GUI 环境的控制之下,并使用以下内容获取 TimeZone(可能不正确,因为我尚未在其他时区对其进行测试)。

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";

还要确保您的 crontab 以用户 (root) 命名,并且也归该用户所有。如果您在内部存储上设置 crontab,以便可以使用 Android 文本编辑器对其进行编辑,则可以将其设为 /data/media/0 的符号链接。我使用 /system/etc/crontabs/root -> /data/media/0/Cron/master

你使用 /data/media 和 /storage 或 /sdcard 因为后者是一个 FUSE 文件系统,它隐藏了底层的 Unix 文件系统权限和所有权,所以你需要在 /data 中设置真实文件系统的所有权。

如果您有一个使用 Fat 或 YAFFS 或其他任何内部存储的旧 Android,那么您可能必须将您的 crontab 保存在 /system 中

请注意,cron 在 Android 下并不总是准时运行,因为它喜欢睡过头。

【讨论】:

添加root用户时应使用>>而不是>以避免覆盖passwd文件:echo "root:x:0:0::/system/etc/crontabs:/system/bin/sh" >> /system/etc/passwd @András Korn 直到最近,Android 根本没有使用该文件。它现在声称是自动生成的,因此请注意更改可能不会持续 哦。很高兴知道。 FWIW,在我的手机上它已经包含了 root 用户,所以不需要更改。【参考方案4】:

这是对 Seff 上述回答的补充。 由于太长,无法将其放在评论中

/system/etc/init.d 并不总能保证工作。就我而言,它没有。以下链接中还提到了其他方法,以防此方法不适合您https://android.stackexchange.com/questions/6558/how-can-i-run-a-script-on-boot/196785

即便如此,crond 也没有为我运行任何工作。 为了调试错误,我杀死了正在运行的实例pkill crond 并像那样运行它

crond -f -d0 -c /data/crontab/

这使 crond 在前台运行并打印所有调试信息。 当我这样运行时,我收到了这个警告

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

所以我必须创建一个带有 root 入口的 passwd 文件

 echo 'root:x:0:0:root:/data:/system/bin/sh' > /system/etc/passwd                                                                                                         

即便如此,它仍然失败并出现类似的错误

crond:  job: 0 /system/bin/ls
crond: child running /bin/sh
crond: can't execute '/bin/sh' for user root

请注意,我在 cronjob 中没有提到“/bin/sh”。这似乎是在二进制文件中硬编码的。

接下来,我在初始化脚本中添加了以下几行

/system/xbin/mount -o remount,rw /
/system/xbin/ln -s /system/bin/ /bin
/system/xbin/mount -o remount,ro /

就是这样。 之后效果很好

【讨论】:

这对我来说非常有效。您提到的所有步骤都是必需的。谢谢! 这里也一样!非常感谢! 什么/在哪里初始化脚本? 请参考上面 Seff 的回答。我的回答只是对他回答的补充

以上是关于如何在 Android 中使用 crontab?的主要内容,如果未能解决你的问题,请参考以下文章

如何用crontab每5分钟执行一次

如何为 crontab 设置 virtualenv?

如何为crontab日志创建文件夹(如果不存在),并根据日期将日志写入特定文件夹?

第二模块命令

使用 PHP 创建、编辑和删除 crontab 作业?

Linux计划任务 Crontab 详解