bash语法 bash是一种Unix shell,用于交互式命令执行和脚本编程。其语法包括变量、条件判断、循环、函数等。
init.rc语法 init.rc是Android初始化语言(Android Init Language)的脚本,用于系统启动时配置系统服务、执行命令等。它的语法相对简单,主要包含动作(action)、服务(service)、命令(command)和选项(option)。
区别概述: 用途:bash用于通用脚本编程,而init.rc用于Android系统初始化。
语法结构:bash具有复杂的编程结构(如循环、条件、函数),init.rc则是声明式的,主要定义服务、触发器和命令。
执行环境:bash脚本在shell中运行,init.rc由init进程解析并执行。
bash语法与init.rc语法对比指南
一、bash语法基础
1. 变量操作
#!/bin/bash# 这是bash脚本的注释# 变量定义(=前后不能有空格)name="World"count=10# 使用变量echo"Hello,$name"# 输出: Hello, Worldecho"Count:${count}"# 输出: Count: 10# 只读变量readonlyPI=3.14# PI=3.1415 # 这行会报错# 删除变量(不能删除只读变量)unsetcountecho"Count:$count"# 输出: Count: (空)执行结果:
Hello, World Count: 10 Count:2. 条件判断
#!/bin/bashnum=10# if-elif-else结构if[$num-gt5];thenecho"数字大于5"# 输出: 数字大于5elif[$num-eq5];thenecho"数字等于5"elseecho"数字小于5"fi# 字符串比较str="hello"if["$str"="hello"];thenecho"字符串匹配"# 输出: 字符串匹配fi# 文件测试if[-f"/etc/passwd"];thenecho"文件存在"# 输出: 文件存在fi执行结果:
数字大于5 字符串匹配 文件存在3. 循环结构
#!/bin/bash# for循环echo"for循环示例:"foriin12345doecho"数字:$i"# 输出1-5done# while循环echo-e"\nwhile循环示例:"counter=1while[$counter-le3]doecho"计数:$counter"# 输出1-3((counter++))# bash算术运算done# until循环echo-e"\nuntil循环示例:"num=1until[$num-gt3]doecho"直到:$num"# 输出1-3num=$((num+1))done执行结果:
for循环示例: 数字: 1 数字: 2 数字: 3 数字: 4 数字: 5 while循环示例: 计数: 1 计数: 2 计数: 3 until循环示例: 直到: 1 直到: 2 直到: 34. 函数定义
#!/bin/bash# 函数定义greet(){localname=$1# 局部变量echo"Hello,$name!"return0# 返回状态码}# 调用函数greet"Alice"# 输出: Hello, Alice!greet"Bob"# 输出: Hello, Bob!# 获取返回值echo"函数返回值:$?"# 输出: 函数返回值: 0执行结果:
Hello, Alice! Hello, Bob! 函数返回值: 0二、init.rc语法基础
1. 基本结构
# init.rc注释以#开头 # 这是Android初始化语言 # 定义服务 service myservice /system/bin/myapp # 服务名和可执行路径 class main # 服务类 user root # 运行用户 group root # 运行组 oneshot # 只运行一次 # 触发器和动作 on boot # 当boot事件触发时 start myservice # 启动服务 mkdir /data/mydir 0775 root root # 创建目录 on property:sys.boot_completed=1 # 属性条件触发 stop myservice # 停止服务2. 完整init.rc示例
# 系统初始化脚本示例 # 导入其他rc文件 import /init.${ro.hardware}.rc # 设置环境变量 export PATH /sbin:/system/bin:/system/xbin # 创建设备节点 mkdir /dev/socket 0775 system system # 挂载文件系统 mount tmpfs tmpfs /mnt mode=0755,uid=0,gid=0 # 定义系统服务 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main # 属于main类 socket zygote stream 660 root system # 创建socket onrestart restart media # 重启时重启media服务 writepid /dev/cpuset/foreground/tasks # 写入pid文件 # 定义普通服务 service my_daemon /system/bin/my_daemon class core # 属于core类 user system # 以system用户运行 group system # 以system组运行 disabled # 默认不启动 capabilities NET_BIND_SERVICE # 设置capabilities # 触发器定义 on early-init # 早期初始化阶段 # 设置安全上下文 setcon u:r:init:s0 # 启动ueventd start ueventd on init # 初始化阶段 # 挂载必要的文件系统 mount proc /proc proc nosuid,nodev,noexec mount sysfs /sys sysfs nosuid,nodev,noexec mount devpts /dev/pts devpts mode=0620,gid=5 on late-init # 后期初始化 # 触发其他事件 trigger post-fs trigger load_system_props on property:persist.sys.debug=1 # 属性触发 # 设置调试模式 setprop debug.trace 1 start debug_service on post-fs-data # 文件系统数据挂载后 # 设置目录权限 chown system system /data/app chmod 0771 /data/app # 命令序列 on boot # 启动基本服务 class_start core # 启动core类所有服务 class_start main # 启动main类所有服务 # 设置系统属性 setprop sys.boot_completed 0 # 执行shell命令 exec /system/bin/logwrapper /system/bin/sh /system/etc/init.sh3. init.rc特有的命令
# 常用init.rc命令示例 # 1. 服务控制命令 start <servicename> # 启动服务 stop <servicename> # 停止服务 restart <servicename> # 重启服务 # 2. 类控制命令 class_start <classname> # 启动类中所有服务 class_stop <classname> # 停止类中所有服务 class_reset <classname> # 重置类中所有服务 # 3. 属性操作 setprop <name> <value> # 设置属性 getprop <name> # 获取属性 # 4. 文件系统操作 mkdir <path> [mode] [owner] [group] # 创建目录 chown <owner> <group> <path> # 修改所有者 chmod <mode> <path> # 修改权限 mount <type> <device> <dir> [flags] # 挂载文件系统 # 5. 其他命令 write <path> <string> # 写文件 copy <src> <dst> # 复制文件 symlink <target> <path> # 创建软链接三、核心区别对比表
| 特性 | bash语法 | init.rc语法 |
|---|---|---|
| 用途 | 通用shell脚本 | Android系统初始化 |
| 执行环境 | bash解释器 | init进程 |
| 注释 | #开头 | #开头 |
| 变量定义 | name="value" | setprop name value |
| 条件判断 | if [条件]; then | on property:name=value |
| 循环结构 | for,while,until | 不支持循环 |
| 函数定义 | function name() { } | 不支持函数 |
| 服务定义 | 无内置概念 | service name path [args] |
| 触发机制 | 需手动调用 | 基于事件/属性触发 |
| 并行执行 | 需要特殊处理 | 支持服务并行启动 |
| 返回值 | $?获取返回值 | 通过属性或状态码 |
四、综合示例对比
bash版本的服务管理脚本:
#!/bin/bash# bash服务管理脚本# 定义服务列表SERVICES=("nginx""mysql""redis")# 启动所有服务start_services(){echo"开始启动服务..."forservicein"${SERVICES[@]}";doifsystemctl start"$service";thenecho"✓$service启动成功"elseecho"✗$service启动失败"return1fidonereturn0}# 检查服务状态check_services(){echo"检查服务状态:"forservicein"${SERVICES[@]}";doifsystemctl is-active --quiet"$service";thenecho"✓$service运行中"elseecho"✗$service未运行"fidone}# 主逻辑case"$1"instart)start_services;;status)check_services;;*)echo"用法:$0{start|status}"exit1;;esacinit.rc版本的服务管理:
# init.rc服务配置 # 定义服务 service nginx /usr/sbin/nginx class main user www-data group www-data oneshot service mysql /usr/sbin/mysqld class main user mysql group mysql socket mysqld stream 660 mysql mysql service redis /usr/bin/redis-server class main user redis group redis # 启动控制 on boot class_start main on property:sys.service.stop=1 class_stop main on property:sys.service.restart=1 class_stop main class_start main五、学习建议
学习bash:
- 重点掌握:变量、条件判断、循环、函数、命令替换
- 实践方法:在Linux终端编写测试脚本
- 调试技巧:使用
set -x调试,echo输出中间值
学习init.rc:
- 重点掌握:service定义、触发器、属性系统、基本命令
- 实践方法:在Android源码环境下测试
- 调试技巧:通过logcat查看init进程日志
共同点:
- 都以
#开头注释 - 都有基本的条件执行逻辑
- 都支持执行系统命令
关键差异:
- bash是完整的编程语言,init.rc是声明式配置语言
- bash侧重流程控制,init.rc侧重服务管理和系统配置
- bash在用户空间运行,init.rc在内核初始化阶段运行
通过对比学习,你可以根据实际需求选择合适的语法:系统初始化用init.rc,自动化脚本用bash。