用户与硬件的关系
stateDiagram
User --> API
API --> User
API --> Kernel
Kernel --> API
Kernel --> Hardware
Hardware --> Kernel
Shell的变量功能
变量定义
-
等号两端不能有空格
-
如有空格
等特殊字符需要加引号" "
- 双引号、单引号都可以
- 双引号里可以加变量,单引号不行
- 字符串里可以使用转义字符
- 数值计算需要双圆括号
1
2
3
|
num3=$(($num1 + $num2))
# 也省略括号中的取值符号
num3=$((num1 + num2))
|
- 简单的字符操作
1
2
3
|
str2=abcdef
echo $str2[2,4] # 角标与元素位置相同
echo $str2[1,-1] # -1代表最后一个字符
|
2.2 变量比较
- 使用双圆括号比较数值
1
2
|
num=123
((num == 123)) && echo good
|
- 使用双方括号比较字符串
1
2
3
|
str=abc
# 注意,两边的变量必须与[]之间留有一个空格!!!
[[ $str == abc ]] && echo good
|
2.3 变量进阶
2.3.1 typeset
2.3.2 local
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
# 强制大小写
# l代表lower u代表upper
local -l(u) str
# 设置环境变量
local -x str
export str
# 设置只读变量
local -r str
# 设置数组不包含重复元素
local -U array
# 设置整数位数
local -Z n num # 设置num的数位为n位。不足补0,超过截断高位
# 设置进制
local -i n num # 设置num为n进制数
[#n] num # 可以显示十进制数为n进制
# 同时对多个变量赋相同而的值
local {a,b,c}=123
# 绑定字符串和数组
local -T(tie) DIR dir
dir=(.. .. ..) # 删除DIR也会删除dir,反之亦然
# 显示变量的定义方式
local -p(print) str
|
三、语句
3.1 条件语句
3.1.1 格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# [[ ]] 用于比较字符串和文件
if [[ ]] {
} elif {
} else {
}
# (())用于比较数值
if (()) {
}
# () 用于在子shell运行命令并判断结果
if () {
}
|
3.1.2 示例
1
2
3
4
5
|
# 此处不需要$
if (( num > 3 && num + 3 <= 10))
{
echo $num
}
|
3.2 循环语句
3.2.1 while与until
1
2
3
4
5
6
7
8
9
|
while [[ ]] 或 (( )) 或 ( ) # 此处同if
{
break/continue
}
until [[ ]] 或 (( )) 或 ( ) # 此处同if
{
break/continue
}
|
3.2.2 for
- 用于枚举
1
2
3
4
5
|
# 枚举括号中的内容
for i ( )
{
}
|
C
风格的for
循环
1
2
3
4
|
for (( i=0; i< 10; i++ ))
{
echo $i
}
|
- 生成数组
1
2
3
4
|
for ({1..10})
{
echo $i
}
|
3.2.3 repeat
1
2
3
4
5
|
# 将代码块中的内容循环n次
repeat n
{
...
}
|
3.3 分支语句
3.3.1 case
1
2
3
4
5
6
|
case $i
{
(a)
echo 1
}
|
3.3.2 select
1
2
3
4
|
select $i (...)
{
}
|
3.4 异常处理语句
1
2
3
4
5
6
|
{
Code 1
} always
{
Code 2
}
|
四、字符串处理
4.1 字符串长度
1
2
3
4
5
6
7
|
#显示字符串长度
echo $#str
# 读取函数或脚本的第一个参数的长度
echo $#1
|
4.2 字符串拼接
1
2
3
4
5
6
|
str1=abc
str2=def
# 第一种拼接方式
str2+=$str1
# 第二种拼接方式
str3=$str1$str2
|
4.3 字符串截断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
str=abcdeabcde
# 删除左端匹配内容,最小匹配
echo ${str#*b}
# 结果
cdeabcde
# 删除右端匹配内容,最大匹配
echo ${str%*d}
# 结果
abcdeabc
# 删除左端匹配内容,最大匹配
echo ${str##*b}
# 结果
cde
# 删除右端匹配到的内容
echo ${str%%d*},最大匹配
# 结果
abc
|
4.4 字符串查找
- 子字符串定位
1
2
3
4
5
6
7
|
str=abcdef
# I 表示从右往左找,i表示从左往右找
echo $str[(I)cd] # $后不能有空格
# 找不到就返回(数组大小+1)
|
4.5 字符串替换
- 只替换找到的第一个
1
2
|
str=abcabc
echo ${str/bc/ef}
|
- 删除匹配到的第一个
- 替换所有找到的
1
|
echo ${str//bc/ef} # 多加一个/
|
- 删除所有匹配的
- 匹配成功就输出空字符串
- 匹配失败就输出原字符串
- 加
M
后效果反转
- 按位置删除(替换)字符串
1
2
|
str[1,4]= # 空值即位删除,否则就是替换
echo $str
|
4.6 判断字符串变量是否存在
1
2
3
|
(($+var)) && echo good
# 存在就返回good
|
- 仅仅用
[["str"==""]]
是无法区分其内容为空还是不存在的
4.7 字符串匹配判断
- 判断是否包含字符串
1
2
3
4
|
str1=abc
str2=bc
[[ $str1 == *$str2* ]] && echo good
|
4.8 大小写转换
- 转成大写
1
2
3
4
5
6
7
|
str="ABCDE abcde"
echo ${(U)str}
# 等价形式
echo ${str:u}
|
- 转成小写
1
2
3
4
5
|
echo ${(L)str}
# 等价形式
echo ${str:l}
|
- 转成首字母大写
4.9 文件目录名截取
1
2
3
|
filepath=/a/b/c.x
echo ${filepath:[hter]}
|
h
取目录名
t
取文件名
e
取文件扩展名,即文件.
后的部分
r
去掉末尾扩展名的路径
4.10 字符串分隔
- 使用空格
作分隔符,多个空格只算一个分隔符
1
2
3
4
5
|
str='aa bb cc dd'
# 显示第n个token
echo ${str[(w)n]}
|
- 指定分隔符
1
2
3
4
5
|
str="aa--bb--cc"
# 设定分隔符为--,并显示第n个token
echo ${str[(ws:--:)n]}
|
4.11 多行字符串
1
2
3
|
# 以下操作可以用于命令行
str="line1
> line2"
|
4.12 读取文件内容到字符串
- 读取整个文件
1
2
3
4
5
6
7
8
9
10
11
12
|
str=$(<filename)
# 注意引号
echo "$(<filename)"
# 遍历每行
for i (${(f)"$(<filename)"})
{
echo $i
}
|
- 读取文件指定行
1
2
3
4
5
6
7
8
9
|
echo ${"$(<text.txt)"[(f)2]}
# 输出包含abc的一行
echo ${"$(<text.txt)"[(fr)*abc*]}
# 从左端输出包含aa的一行,但从左端截去"line"
echo ${"$(<text.txt)"[(fr)*aa*]#line}
|