在Android的init
进程中,command
是用于定义启动时要执行的具体命令行指令的关键部分。init
进程是Android系统启动的第一个进程,它负责初始化系统的各个组件,并启动必要的服务。command
可以在init.rc
文件及其包含的其他.rc
文件中找到,通常作为on
操作块或service
定义的一部分。
1. command
的基本概念
command
是一条或多条具体的命令行指令,它们在特定条件下由init
进程执行。这些命令可以用来创建目录、设置权限、启动服务、写入系统属性等。每个命令必须以空格分隔,并且在同一行上执行。如果需要多行命令,可以使用反斜杠(\
)进行换行。
2. 常见的command
类型
以下是一些常见的command
及其用途:
2.1 创建和管理文件系统
-
rcmkdir <path> [mode] [user] [group]
:创建一个目录,并设置其权限、用户和组。深色版本
mkdir /data/myapp 0755 root root
-
rcchmod <mode> <path>
:更改文件或目录的权限。深色版本
chmod 0755 /data/myapp
-
rcchown <user>:<group> <path>
:更改文件或目录的所有者和组。深色版本
chown system:system /data/myapp
-
rcmount <type> <device> <dir> [flags]
:挂载文件系统。深色版本
mount ext4 /dev/block/mmcblk0p1 /data
-
rcumount <dir>
:卸载文件系统。深色版本
umount /data
2.2 设置环境变量和系统属性
-
rcexport <variable> [value]
:设置环境变量。深色版本
export PATH=/system/bin:$PATH
-
rcwrite <path> <text>
:将文本写入文件。深色版本
write /sys/class/leds/led1/brightness 1
-
rcsetprop <property> <value>
:设置系统属性。深色版本
setprop sys.boot_completed 1
-
rcgetprop <property>
:获取系统属性的值(通常用于条件判断)。深色版本
on property:getprop(sys.boot_completed)=1start myservice
2.3 启动和管理服务
-
rcstart <service>
:启动指定的服务。深色版本
start adbd
-
rcstop <service>
:停止指定的服务。深色版本
stop adbd
-
rcrestart <service>
:重启指定的服务。深色版本
restart adbd
-
rcclass_start <class>
:启动属于指定类的所有服务。深色版本
class_start main
-
rcclass_stop <class>
:停止属于指定类的所有服务。深色版本
class_stop main
2.4 日志和调试
-
rclog <message>
:将消息写入系统日志。深色版本
log "Starting my custom service"
-
rcexec <command> [args...]
:执行外部命令,并等待其完成。深色版本
exec -- /system/bin/log -t "myapp" "Custom initialization completed"
2.5 其他命令
-
rctrigger <event>
:触发自定义事件。深色版本
trigger custom_event
-
rcwait <path> [timeout]
:等待指定路径存在,直到超时。深色版本
wait /dev/block/mmcblk0p1 10
-
rcsymlink <target> <link>
:创建符号链接。深色版本
symlink /data/myapp /mnt/myapp
-
rcinsmod <module> [args...]
:加载内核模块。深色版本
insmod /system/lib/modules/wlan.ko
-
rcrm <path>
:删除文件或目录。深色版本
rm /data/myapp/tmp/*
-
rcrmdir <path>
:删除空目录。深色版本
rmdir /data/myapp/tmp
3. 怎样添加新的命令command
查看command定义的地方,
system/core/init/builtins.cpp
1029// Builtin-function-map start
1030const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
1031 constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
1032 // clang-format off
1033 static const Map builtin_functions = {
1034 {"bootchart", {1, 1, {false, do_bootchart}}},
1035 {"chmod", {2, 2, {true, do_chmod}}},
1036 {"chown", {2, 3, {true, do_chown}}},
1037 {"class_reset", {1, 1, {false, do_class_reset}}},
1038 {"class_restart", {1, 1, {false, do_class_restart}}},
1039 {"class_start", {1, 1, {false, do_class_start}}},
1040 {"class_stop", {1, 1, {false, do_class_stop}}},
1041 {"copy", {2, 2, {true, do_copy}}},
1042 {"domainname", {1, 1, {true, do_domainname}}},
1043 {"enable", {1, 1, {false, do_enable}}},
1044 {"exec", {1, kMax, {false, do_exec}}},
1045 {"exec_background", {1, kMax, {false, do_exec_background}}},
1046 {"exec_start", {1, 1, {false, do_exec_start}}},
1047 {"export", {2, 2, {false, do_export}}},
1048 {"hostname", {1, 1, {true, do_hostname}}},
1049 {"ifup", {1, 1, {true, do_ifup}}},
1050 {"init_user0", {0, 0, {false, do_init_user0}}},
1051 {"insmod", {1, kMax, {true, do_insmod}}},
1052 {"installkey", {1, 1, {false, do_installkey}}},
1053 {"load_persist_props", {0, 0, {false, do_load_persist_props}}},
1054 {"load_system_props", {0, 0, {false, do_load_system_props}}},
1055 {"loglevel", {1, 1, {false, do_loglevel}}},
1056 {"mkdir", {1, 4, {true, do_mkdir}}},
1057 // TODO: Do mount operations in vendor_init.
1058 // mount_all is currently too complex to run in vendor_init as it queues action triggers,
1059 // imports rc scripts, etc. It should be simplified and run in vendor_init context.
1060 // mount and umount are run in the same context as mount_all for symmetry.
1061 {"mount_all", {1, kMax, {false, do_mount_all}}},
1062 {"mount", {3, kMax, {false, do_mount}}},
1063 {"umount", {1, 1, {false, do_umount}}},
1064 {"readahead", {1, 2, {true, do_readahead}}},
1065 {"restart", {1, 1, {false, do_restart}}},
1066 {"restorecon", {1, kMax, {true, do_restorecon}}},
1067 {"restorecon_recursive", {1, kMax, {true, do_restorecon_recursive}}},
1068 {"rm", {1, 1, {true, do_rm}}},
1069 {"rmdir", {1, 1, {true, do_rmdir}}},
1070 {"setprop", {2, 2, {true, do_setprop}}},
1071 {"setrlimit", {3, 3, {false, do_setrlimit}}},
1072 {"start", {1, 1, {false, do_start}}},
1073 {"stop", {1, 1, {false, do_stop}}},
1074 {"swapon_all", {1, 1, {false, do_swapon_all}}},
1075 {"symlink", {2, 2, {true, do_symlink}}},
1076 {"sysclktz", {1, 1, {false, do_sysclktz}}},
1077 {"trigger", {1, 1, {false, do_trigger}}},
1078 {"verity_load_state", {0, 0, {false, do_verity_load_state}}},
1079 {"verity_update_state", {0, 0, {false, do_verity_update_state}}},
1080 {"wait", {1, 2, {true, do_wait}}},
1081 {"wait_for_prop", {2, 2, {false, do_wait_for_prop}}},
1082 {"write", {2, 2, {true, do_write}}},
1083 };
1084 // clang-format on
1085 return builtin_functions;
1086}
参考这里的实现,在这里添加命令,并进行相关的实现即可
4. 其他方法
添加命令笔记麻烦,可以在init.rc里调用程序或者脚本文件来实现类似的功能,
参考
init.rc 启动 shell 脚本 开机执行脚本 init.rc执行shell脚本_init.rc执行sh脚本内容需要权限吗-CSDN博客
android 系统rc添加 shell运行脚本_android13 在rc文件中执行脚本-CSDN博客
init execute_no_trans avc报错-CSDN博客