我找不到答案,想问一个问题:是否可以使用busybox
(或其他方式)来运行crontab
以重新启动Android?
尝试运行crontab时,它报告未知的uid 0。
尝试运行reboot,但它没有任何作用。
还是说我现在在寻求不可能的东西?
需求
Root访问权限:用于超级用户命令,例如重启或init.d配置。Crond仍然可以在普通用户特权下运行。
Busybox:用于'crond'服务
(可选) init.d支持:启动引导时的'crond'服务。或通过Magisk post-fs-data.d脚本启动。
创建定期作业
在目录/data/crontab/(甚至可以是sdcard中的任何可访问目录)中创建cronjob文件,并将文件名命名为“root”。 在文件“root”中编写您的cronjob。
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
示例cron作业
53 * * * * reboot
将在每小时的第53分钟重新启动您的设备。
注意: 1. 如果您修改了crontab,请记得在杀死现有的crond后重新启动守护程序。
如果crond没有遵守您的时区,您可能需要在设备上更新tzdata。
最好使用 */1 * * * * 进行测试以查看是否正常工作。
/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 (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
/system/xbin/mount -o remount,rw /
/system/xbin/ln -s /system/bin/ /bin
/system/xbin/mount -o remount,ro /
就是这样。之后一切都工作正常。
mount -o rw,remount /dev/stl12 /system
mount -o ro,remount /dev/stl12 /system
你可能需要设置你的时区并添加一个root用户。像这样添加一个root用户:
echo "root:x:0:0::/system/etc/crontabs:/system/bin/sh" > /system/etc/passwd
获取正确的时区字符串有些奇怪。将TZ环境变量设置为时区字符串,并确保crond获得它。我将其控制在GUI环境下,并使用以下内容获取时区(可能不正确,因为我尚未在其他时区上进行测试)。
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,则可能必须将crontabs保留在/system中。
请注意,在Android下,cron不总是按时运行,因为它喜欢睡过头。
>>
而不是>
,以避免覆盖passwd
文件:echo "root:x:0:0::/system/etc/crontabs:/system/bin/sh" >> /system/etc/passwd
- András Korn使用Termux在启动时自动启动,使用Macrodroid方法,并在后台保持运行的方法。我在已Root的设备上使用它,但我认为在任何未Root的设备上也应该可以使用:
从Playstore安装Termux,或者对于旧的Android 5.x.x/6.x.x设备,安装最后一个可用版本termux-v0.79-offline-bootstraps.apk,例如从https://archive.org/download/termux-repositories-legacy/下载
请注意,如果您使用的是旧的Android 5-6并使用termux-v0.79-offline-bootstraps.apk:您必须稍微调整一下存储库列表:
$ nano /data/data/com.termux/files/usr/etc/apt/sources.list
# Comment out:
#deb https://termux.net stable main
#Add:
deb https://packages.termux.dev/termux-main-21 stable main
删除游戏和科学存储库
$ pkg remove science-repo
$ pkg remove game-repo
更新(选择默认所有答案-按Enter键)
$ pkg update
为了让Termux在启动时启动,我使用Macrodroid:它可以在我曾经使用过的几乎所有旧或新的Android手机/平板电脑上运行。创建一个新的宏:触发器:(a)'设备启动',操作:(a)'启动Termux',(b)'等待10秒',(c)'启动主屏幕'。 (Macrodroid的屏幕截图)。检查它是否在重新启动时工作。现在应该启动Termux并放在后台。
在我使用的版本termux-v0.79-offline-bootstraps.apk中,默认似乎安装了crond。尝试:$ crond
,并使用$ pgrep crond
检查守护程序crond是否正在运行。如果有问题,请在其他地方检查如何在Termux中安装crond。
为了在Termux启动时执行crond,请在目录/data/data/com.termux/files/usr/etc/profile.d/中添加一个启动脚本(例如startup-crond)。此目录中的所有脚本都会在每次新登录时在bash的启动脚本中进行源代码处理。
/data/data/com.termux/files/usr/etc/profile.d/startup-crond的内容
if pgrep "crond" >/dev/null; then
echo "crond is already running"
else
echo "Starting crond ..." && crond && echo "[OK]"
fi
确保文件可执行:$ chmod 775 startup-crond
这样,每次启动Termux时,.../usr/etc/profile.d/startup-crond都会检查crond是否正在运行,如果没有,则会启动守护程序。 "[OK]"消息确认一切正常。
使用$ crontab -e
在termux中添加您的crontab条目(使用vi编辑器)。这将在/data/data/com.termux/files/usr/var/spool/cron/crontabs/中创建一个带有Termux-App用户名的文件。 crontab的名称是Termux的用户名。您可以使用$ whoami
进行确认。如果您不喜欢vi,也可以手动查看/编辑上述文件的内容。例如,使用nano。
请注意,正如其他作者所提到的,这是用户级别的crontab,其语法为* * * * * my-script
。与Linux的系统/etc/crontab不同,不要在my-script之
与问题有些松散的联系,但在通过ssh工作时仍然很有趣:
$ pkg install openssh
,用$ passwd
创建密码,启动$ sshd
,用$ ifconfig
找到您的Android IP,在wlan0下查找条目:inet 192.168.XXX.XXX,从桌面登录到您的Android设备,使用$ ssh 192.168.XXX.XXX -p 8022
)。当在Termux内部时,我还强烈建议使用Midnight-Commander浏览目录:$ pkg install mc
这个应用程序运行得非常好:
https://f-droid.org/packages/it.faerb.crond/
cron格式是“用户”格式而不是“系统”格式,所有用户都以root身份运行。
这是我如何每天重新启动我的LineageOS 18.1 Android安装:
# 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