每次开机执行自定义脚本?)
如何用 KernelSU 的 /data/adb 通用脚本目录post-fs-data.d、service.d 等每次开机执行自定义脚本【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU如果你的设备已经装好 KernelSU并且希望某个自定义 shell 脚本在每次开机时都自动运行而不是打包成一个模块KernelSU 提供了/data/adb下的“通用脚本目录”general scripts把脚本放进对应目录并赋予可执行权限KernelSU 就会在开机的相应阶段替你执行。本文基于 Module guide 中的Boot scripts章节说明各目录对应哪个开机阶段、如何放置脚本、脚本运行环境以及怎么判断它确实执行了。四个通用脚本目录分别对应哪个开机阶段KernelSU 的开机脚本按存储位置分为通用脚本general scripts和模块脚本module scripts。与本文任务相关的是通用脚本共四个目录目录执行阶段阶段特性/data/adb/post-fs-data.d/post-fs-dataBLOCKING启动流程会暂停直到脚本执行完成或到达 10 秒上限/data/adb/service.d/late_start serviceNON-BLOCKING脚本与其余启动流程并行运行/data/adb/post-mount.d/post-mountOverlayFS 挂载模块完成后执行/data/adb/boot-completed.d/boot completed系统发出ACTION_BOOT_COMPLETED广播后执行另外在 late-load 模式下还可以把通用脚本放在/data/adb/late-load.d/它在该模式下替代post-fs-data阶段执行详见 Module guide 的Late-load mode章节。阶段选择上官方文档的态度很明确post-fs-data 阶段在 Zygote 启动之前执行且发生在任何模块挂载之前该阶段是阻塞的非必要不要把脚本放在这里。late_start service 阶段service.d是文档推荐的默认选择适合大多数开机脚本。需要等启动完全结束后再做的事如启动应用、依赖系统服务的操作用boot-completed.d。放置脚本并设置可执行权限通用脚本有且只有一个硬性条件脚本必须设置为可执行否则不会被执行chmod x /data/adb/service.d/my_script.sh放置流程以最常见的service.d为例编写脚本例如/data/adb/service.d/my_script.sh。用上面的chmod x命令加上可执行权限。重启设备脚本会在 late_start service 阶段执行此后每次开机都会重复执行。两个与“模块脚本”相关的重要边界来自 Module guide模块不应该在安装时添加通用脚本Modules should NOT add general scripts during installation。也就是说/data/adb/*.d目录是给系统级/手工维护的脚本用的如果你的脚本归属于某个模块应该把它放进该模块目录post-fs-data.sh、service.sh、post-mount.sh、boot-completed.sh由模块机制按模块启用状态决定是否执行。模块脚本使用MODDIR${0%/*}获取模块目录路径不要硬编码路径通用脚本不属于模块没有这个约定。脚本运行环境所有开机脚本包括通用脚本都在 KernelSU 自带的 BusyBoxashshell 中、且以 Standalone Mode 执行。这意味着shell 中的ls、rm、chmod等命令直接调用 BusyBox 内建 applet而不是$PATH里的/system/bin/...脚本在任何 Android 版本下都有完整的命令集。BusyBox 二进制位于/data/adb/ksu/bin/busybox。如果想在 KernelSU 之外用同样的 Standalone Mode 运行脚本文档给出的方式是ASH_STANDALONE1 /data/adb/ksu/bin/busybox sh script或/data/adb/ksu/bin/busybox sh -o standalone script。脚本中可以通过环境变量KSU判断当前运行在 KernelSU 还是 Magisk 环境在 KernelSU 中其值为true见 Difference with Magisk。由于 BusyBox 与 Magisk 使用的是同一套二进制Magisk 的脚本写法可以直接沿用。如果脚本确实要放在阻塞的 post-fs-data 阶段有一条硬性警告来自文档在这个阶段使用setprop会死锁启动流程必须改用resetprop -n prop_name prop_value。如何确认脚本在正确的时机执行判断执行时机可以直接对照 Module guide 中Boot scripts process explanation给出的启动流程post-fs-data.d/的脚本在post-fs-data阶段执行此时 Zygote 尚未启动该阶段阻塞启动最长等待 10 秒——如果脚本卡住启动也会在 10 秒后被强制继续。service.d/的脚本在“kernel2user init”开机动画出现后阶段执行与class_start main等动作处于同一时期是非阻塞的。boot-completed.d/的脚本在boot complete广播ACTION_BOOT_COMPLETED事件之后执行。也就是说如果你观察到脚本的副作用发生在上锁屏界面可用阶段 3之前还是之后就能反推出它属于哪个阶段、是否放错了目录。此外如果你的设备使用 late-load 模式通过ksud late-load在开机完成后才加载内核模块注意标准流程中的post-fs-data.sh/post-fs-data.d/不会执行而是由late-load阶段/data/adb/late-load.d/替代service.d/、post-mount.d/、boot-completed.d/则照常执行。脚本内可以用文档给出的方式检测该模式if [ $KSU_LATE_LOAD 1 ]; then # Running in late-load mode echo Late-load mode detected fi限制与容易混淆的边界post-fs-data 阶段阻塞启动文档建议“Only run scripts in this mode if necessary”能放service.d就不要放post-fs-data.d。late-load 模式的差异除post-fs-data被替代外late-load 模式下 initrc 注入不可用、安全模式检测始终禁用、启动日志抓取logcat/dmesg被跳过。如果你的设备是 late-load 加载 KernelSU 的 LKM按上表的对应关系调整目录选择即可。不要用.rc替代脚本KernelSU 还支持把.rc文件放进/data/adb/initrc.d/通用或模块的initrc/模块级注入 init.rc但通用initrc.d/里的文件必须有可执行权限且注入发生在 post-fs-data 之前的 init 阶段——它是注册 init service/属性触发器用的与“执行 shell 脚本”是两套机制不要把二者混用。通用脚本不属于模块因此不依赖任何模块是否启用只要 KernelSU 正常工作且脚本有可执行权限每次开机都会执行。如果你后续要处理的不是“开机跑脚本”而是脚本需要访问/system文件替换system目录挂载那属于 metamodule 的职责参见 Metamodule guide仅使用脚本、sepolicy、system.prop 等功能的模块不需要安装 metamodule。【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考