前言
在安卓源码里,离不开两个东西,一个就是.sh文件,还有一个就是.mk文件。
这两个文件各持有一个语法,一个是Makefile语法,一个是Shell脚本语法。
这两个是真的让我头疼,就像看天书一样,呜呜呜。
1、变量
完整的变量打印:
name="乌鸡哥" echo ${name}
简写:
name="乌鸡哥" echo $name
乌鸡哥
实例:
一开始没有namess这个变量,所以没有输出。
后来我添加了,就有输出了。
最后我删除了变量namess,又没有输出了。
1)变量输出长度
name="乌鸡哥" echo ${#name}
4
2)提取子字符串
以下实例从字符串第 2 个字符开始截取 4 个字符:
string="runoob is a great site" echo ${string:1:4} # 输出 unoo
注意:第一个字符的索引值为 0。
3)查找子字符串
查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):
string="runoob is a great site" echo `expr index "$string" io` # 输出 4
注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。
4)单引号和双引号的区别
在 shell 脚本中,echo命令用于输出字符串或者变量的值。在使用echo命令时,可以使用反引号、单引号或双引号来包围要输出的内容。
你们猜猜下面打印结果是什么?
name="乌鸡哥" name2='${name}' name3="${name}" ... echo $name echo $name2
结果如下:
乌鸡哥
${name}
乌鸡哥
1.反引号(``):反引号用于将要执行的命令包围起来,并将命令的输出作为参数传递给 echo 命令。例如:
echo "Today is `date +%A`"
这个命令会将 date +%A 命令输出的结果插入到 echo 命令中进行输出。
2.单引号('):单引号用于将其中的内容视为字面值进行输出,不进行任何解释和替换。例如:
echo 'The value of $HOME is' $HOME
这个命令会输出 The value of $HOME is /home/user,其中 $HOME 被视为普通字符输出,而不会被解释为变量。
3.双引号("):双引号用于将其中的内容进行变量替换和转义解析等操作,并将其作为一个整体进行输出。例如:
name='John' echo "Hello, $name!"
这个命令会输出 Hello, John!,其中 $name 会被自动替换为变量的值。
需要注意的是,在使用双引号和反引号时,如果其中包含特殊字符或者空格等不安全的字符,需要进行适当的转义处理,以避免出现意外的错误。
单引号变量,不识别特殊语法;
双引号变量,识别特殊符号。
5)特殊变量
查看上条命令是否执行成功。
● $?
○ 0:成功
○ 1-255:错误码
实例:
另外,还有几个特殊字符用来处理参数(调用函数传参,命令行传参等…):
● $*:以一个单字符串显示所有向脚本传递的参数。如∗用「“」括起来的情况、以”∗用「“」括起来的情况、以”*用「“」括起来的情况、以”1 2…2…2 … n"的形式输出所有参数。
● $@:与$*相同,但是使用时加引号,并在引号中返回每个参数。如@用「“」括起来的情况、以”@用「“」括起来的情况、以”@用「“」括起来的情况、以”1" “2 " … " 2" … "2"…"n” 的形式输出所有参数。
● $$:脚本运行的当前进程ID号
● $!:后台运行的最后一个进程的ID号
● $#:传递到脚本的参数个数
● $-:显示Shell使用的当前选项,与set命令功能相同。
● $?:显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。还有一个作用就是函数返回值在调用该函数后通过 $? 来获得。
6)脚本里变量的赋值情况
1.每次调用bash/sh解释器,都会开启一个子shell,不保留当前的shell变量,通过pstree检查进程树。(用bash执行脚本里面的变量赋值不被保存)
2.source或.是在当前shell环境加载脚本,因此保留变量。(用source执行脚本里面的变量赋值会被保存)
7)变量存储命令的内容
name=ls #显示ls echo $name
name='ls' #显示当前目录的文件 echo ${name}
8)环境变量
环境变量一般指的是用export内置命令导出的变量,用于定义shell的运行环境、保证shell命令的正确执行。
shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。环境变量可以在命令行中临时创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件。
某个远程登录用户专属配置文件(局部变量)
● ~/.bash_profile(系统优先加载所有全局环境变量和 shell 函数)
● ~/.bashrc (在 ~/.bash_profile中被加载,相当于套娃),用户在登录的时候会去加载~/.bash_profile和 ~/.bashrc文件
所有用户共有(全局变量)
● /etc/profile (系统优先加载)
● /etc/bashrc ,且系统建议最好创建在 /etc/profile.d/,而非直接修改主文件,修改全局配置文件,影响所有登录系统的用户
在 Linux 和类 Unix 系统中,全局的 Bash Shell 配置数据通常被保存在 /etc/profile 与 /etc/bashrc 文件中。这些文件包含所有用户共享的系统级别的配置和环境变量信息。
当操作系统启动时,Bash Shell 会首先执行 /etc/profile 脚本以加载所有全局环境变量和 shell 函数。对于每个新的 Bash 终端窗口,系统还将自动执行 /etc/bashrc 文件中的某些特定配置命令。
在更推荐的做法是创建自己的配置脚本并将其存储在 /etc/profile.d/ 目录下。这样,管理员可以随意创建单独的配置文件来自定义系统级别的平台和服务特定参数,而不必修改 /etc/profile 或 /etc/bashrc 文件。
例如,可以为每个服务或应用程序创建单独的配置文件,并将其放置在 /etc/profile.d/ 目录中,该目录中的任何 .sh 文件都会被整合到系统全局的 Bash 环境中。最后,每次启动新的 Bash 终端窗口时,系统都会自动执行这些文件中包含的命令和设置环境变量,实现系统环境的自动化配置。
检查系统环境变量的命令
● set:输出所有变量,包括全局变量、局部变量
● env:只显示全局变量
● declare:输出所有的变量,如同set
● export:显示和设置环境变量值
撒销环境变量
● unset+变量名,删除变量或函数
设置只读变量
● readonly:只有shell结束,只读变量才失效
直接readonly 显示当前系统只读变量 [root@chaogelinux ~]# readonly name="超哥 [root@chaogelinux ~]# name="chaochao" -bash: name: 只读变量
2、数组
支持一维数组(不支持多维数组),并且没有限定数组的大小,数组元素的下标由 0 开始编号。
1)定义数组
在 Shell 中,用括号来表示数组,初始化时不需要定义数组大小(与 PHP 类似),数组元素用"空格"符号分割开。定义数组的一般形式为:
数组名=(值1 值2 … 值n)
array_name=(A B "C" D)
还可以单独定义数组的各个分量
数组名[下标值]=变量值
array_name[0]=value0
2)读取数组
读取数组元素值的一般格式是:
# ${数组名[下标]} valuen=${array_name[n]}
例如:
#使用 @ 符号可以获取数组中的所有元素,例如: echo ${array_name[@]}
#我们尝试打印一下数组元素。 array_name=(A B "C" D) echo "第二个元素为: ${array_name[1]}" echo "第三个元素为: ${array_name[2]}"
打印出来后你觉得加了双引号的会有区别吗?
答案是没有哦,打印出来都一样。
B
C
最后
#结合上述知识点 # 取得数组元素的个数 length=${#array_name[@]} # 或者 length=${#array_name[*]} # 取得数组单个元素的长度 lengthn=${#array_name[n]}
3)关联数组
declare 是一个 shell 内置命令,在 Linux 和其他类 Unix 系统中都可以使用。它用于声明变量的类型和属性,以及定义函数等。下面是一些 declare 命令的常见用法:
1.声明普通变量
declare variable_name=value
这个命令将创建一个名为 variable_name 的变量,并将其初始化为指定的值。
2.声明只读变量
declare -r variable_name=value
这个命令将创建一个只读的名为 variable_name 的变量,并将其初始化为指定的值。只读变量的值不能被修改或重新赋值。
3.声明整数变量
declare -i variable_name=value
这个命令将创建一个名为 variable_name 的整型变量,并将其初始化为指定的值。如果后续对该变量进行了非整型的赋值操作,系统会尝试自动转换为整型。
4.声明数组变量
declare -a array_name
这个命令将创建一个名为 array_name 的数组变量。在后续的操作中,可以使用数组下标来访问和赋值数组元素。
5.声明关联数组变量
declare -A associative_array_name
这个命令将创建一个名为 associative_array_name 的关联数组变量。在后续的操作中,可以使用任意字符串作为数组下标来访问和赋值数组元素。
6.声明函数
declare -f function_name
这个命令将打印名为 function_name 的函数的定义。如果不加参数,则会列出所有已经定义的函数。
除了上述用法外,declare 命令还支持一些其他的选项和参数,可以通过 help declare 命令来查看它们的详细说明。
我们这里详细介绍第五点
在 Bash shell 中,关联数组(associative array)是一种特殊的数组类型,它使用任意字符串作为下标来访问和赋值数组元素。关联数组也被称为哈希表(hash table)、字典(dictionary)或映射(map)。
要声明一个关联数组变量,可以使用 declare 命令的 -A 选项,例如:
declare -A my_array
也可以这样直接定义:
declare -A my_array=(["name"]="John" ["age"]="30")
这里,我们使用关联数组下标 "name" 和 "age" 来分别给数组元素赋值。
my_array["name"]="John" my_array["age"]=30
在后续的操作中,可以使用任何字符串作为数组下标来访问和赋值数组元素,例如:
echo "My name is ${my_array["name"]} and I am ${my_array["age"]} years old."
打印数组的所有value:
# 两者等效 echo "数组的元素为: ${my_array[*]}" echo "数组的元素为: ${my_array[@]}"
数组的元素为: John 30
打印数组的所有key:
echo "数组的键为: ${!site[*]}" echo "数组的键为: ${!site[@]}"
数组的键为: name age
打印数组的元素个数:
echo "数组元素个数为: ${#my_array[*]}" echo "数组元素个数为: ${#my_array[@]}"
数组元素个数为: 2
需要注意的是,在关联数组中,每个元素都与一个独立的字符串键相关联。因此,在访问数组元素时,可以使用任何合法的字符串作为下标,包括空字符串、特殊字符和空格等。与普通数组不同,关联数组不需要事先指定数组的长度,也不需要在定义时初始化数组元素。
3、注释
# 别学习了 好好睡觉(单行注释)
# 多行注释(Here Document) : <<END_COMMENT 注释内容... 注释内容... 注释内容... END_COMMENT
# 举个栗子 # 这段代码先执行 Here Document (<<)语法结构,可以看成标准输入 # 将内容传递给 cat 命令作为标准输入 # 然后再将 cat 命令的输出结果重定向(>)到文件中 # 最终将字符串 "五级五级" 和 "66666666" 写入到 77.sh 文件中。 cat > device/$1/$2/vendorsetup.sh << EOF echo "五级五级" echo "66666666" EOF