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. 变量操作
bash
#!/bin/bash
# 这是bash脚本的注释
# 变量定义(=前后不能有空格)
name="World"
count=10
# 使用变量
echo "Hello, $name" # 输出: Hello, World
echo "Count: ${count}" # 输出: Count: 10
# 只读变量
readonly PI=3.14
# PI=3.1415 # 这行会报错
# 删除变量(不能删除只读变量)
unset count
echo "Count: $count" # 输出: Count: (空)
执行结果:
Hello, World
Count: 10
Count:
2. 条件判断
bash
#!/bin/bash
num=10
# if-elif-else结构
if [ $num -gt 5 ]; then
echo "数字大于5" # 输出: 数字大于5
elif [ $num -eq 5 ]; then
echo "数字等于5"
else
echo "数字小于5"
fi
# 字符串比较
str="hello"
if [ "$str" = "hello" ]; then
echo "字符串匹配" # 输出: 字符串匹配
fi
# 文件测试
if [ -f "/etc/passwd" ]; then
echo "文件存在" # 输出: 文件存在
fi
执行结果:
数字大于5
字符串匹配
文件存在
3. 循环结构
bash
#!/bin/bash
# for循环
echo "for循环示例:"
for i in 1 2 3 4 5
do
echo "数字: $i" # 输出1-5
done
# while循环
echo -e "\nwhile循环示例:"
counter=1
while [ $counter -le 3 ]
do
echo "计数: $counter" # 输出1-3
((counter++)) # bash算术运算
done
# until循环
echo -e "\nuntil循环示例:"
num=1
until [ $num -gt 3 ]
do
echo "直到: $num" # 输出1-3
num=$((num + 1))
done
执行结果:
for循环示例:
数字: 1
数字: 2
数字: 3
数字: 4
数字: 5
while循环示例:
计数: 1
计数: 2
计数: 3
until循环示例:
直到: 1
直到: 2
直到: 3
4. 函数定义
bash
#!/bin/bash
# 函数定义
greet() {
local name=$1 # 局部变量
echo "Hello, $name!"
return 0 # 返回状态码
}
# 调用函数
greet "Alice" # 输出: Hello, Alice!
greet "Bob" # 输出: Hello, Bob!
# 获取返回值
echo "函数返回值: $?" # 输出: 函数返回值: 0
执行结果:
Hello, Alice!
Hello, Bob!
函数返回值: 0
二、init.rc语法基础
1. 基本结构
rc
# 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
# 系统初始化脚本示例
# 导入其他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.sh
3. init.rc特有的命令
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版本的服务管理脚本:
bash
#!/bin/bash
# bash服务管理脚本
# 定义服务列表
SERVICES=("nginx" "mysql" "redis")
# 启动所有服务
start_services() {
echo "开始启动服务..."
for service in "${SERVICES[@]}"; do
if systemctl start "$service"; then
echo "✓ $service 启动成功"
else
echo "✗ $service 启动失败"
return 1
fi
done
return 0
}
# 检查服务状态
check_services() {
echo "检查服务状态:"
for service in "${SERVICES[@]}"; do
if systemctl is-active --quiet "$service"; then
echo "✓ $service 运行中"
else
echo "✗ $service 未运行"
fi
done
}
# 主逻辑
case "$1" in
start)
start_services
;;
status)
check_services
;;
*)
echo "用法: $0 {start|status}"
exit 1
;;
esac
init.rc版本的服务管理:
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。