如何在 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 crond
或 ps | 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 /system
和mount -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?的主要内容,如果未能解决你的问题,请参考以下文章