分支/循环语句块不可为空,如果不需要就不要写,如果确实需要,就用
:
内置命令占位。
if
if 根据 condition 的 退出状态码 决定是否执行,0 是 真(条件成立),非 0 是 假(条件不成立)。
常用的条件测试命令有:test
、[
、[[
,它们的具体用法已在前一篇中给出,这里就不再复述了。
1
2
3
4
5
6
if condition; then
command1
command2
...
commandN
fi
if…else
如果 condition 成立,则执行 if 分支,否则执行 else 分支。
1
2
3
4
5
6
7
8
9
if condition; then
command1
...
commandN
else
command1
...
commandN
fi
if…elif…else
从上至下依次评估,如果条件成立,则执行对应分支(匹配结束);
如果所有条件都不成立,则执行 else 分支(当然,可以没有 else 分支)。
1
2
3
4
5
6
7
8
9
if condition; then
...
elif condition; then
...
elif condition; then
...
else
...
fi
foreach
用于遍历(枚举)指定的元素列表。
- 传递给 foreach 的元素列表其实和传递给命令的参数列表一样,会使用空白符进行分词
- 如果元素内容包含空白符(如空格),必须使用引号包围,否则会被作为多个元素处理
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
## 指定元素列表(空格隔开,如果元素内容包含空白符,请使用引号包围)
for var in item1 item2 item3 ... itemN; do
command1
command2
...
commandN
done
## 如果省略 in 列表,则遍历参数(脚本命令行参数或函数的位置参数)
for arg; do
echo "$arg"
done
## 遍历数组 (双引号)
for elem in "${array[@]}"; do
command1
command2
...
commandN
done
## 遍历参数 (双引号)
for arg in "$@"; do
command1
command2
...
commandN
done
关于 "${array[@]}"
和 "$@"
:
必须使用双引号包围,否则无法正确处理数组元素/位置参数中包含空白符的情况(会被当做分隔符)。
只要是双引号中带 @
的表达式,shell 都会先展开里面的元素,如 "$@"
,相当于 "$1" "$2" "$3" ...
。
在进行 “参数转发” 时也经常使用 "$@"
、"${array[@]}"
等表达式,它们也会被自动展开,例如:
test.sh
1
2
3
4
5
6
7
8
9
#!/bin/bash
main() {
for arg in "$@"; do
echo "$arg"
done
}
main $@ # 没引号
echo '-----------'
main "$@" # 双引号
执行结果
1
2
3
4
5
6
7
8
9
10
11
$ ./test.sh 1 2 3 '4 5'
1
2
3
4
5
-----------
1
2
3
4 5
for
C/C++ 风格的 for() 循环,使用双重圆括号。
1
2
3
for ((i = 0; i < 10; i++)); do
echo $i
done
while
如果 condition 成立,则执行循环体,否则退出循环。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
while condition; do
...
done
## 无限循环 - 1
while true; do # 因为 true 总是返回真
...
done
## 无限循环 - 2
while :; do # 因为 : 总是返回真
...
done
## 无限循环 - 3
for ((;;)) do # for 无限循环 (C/C++ 风格)
...
done
until
如果 condition 不成立,则执行循环体,否则退出循环。和 while 相反。
1
2
3
until condition; do
...
done
case
if…elif…elif…else 的简化直观版本,相当于 C 语言的 switch 语句。
globbing 即 shell 通配符,case 还在此基础上添加了对|
选择元字符的支持。
因此,在 case 中,支持*
、?
、[]
、[^]
、|
五种模式匹配元字符。
解释一下|
,它和 regex 中的|
是一样的,或的意思,用来选择多个模式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
case var in
globbing1)
command1
...
commandN
;;
globbing2)
command1
...
commandN
;;
globbing3)
command1
...
commandN
;;
*)
command1
...
commandN
;;
esac
break、continue
break
:跳出当前循环,执行循环后面的语句;continue
:结束本轮循环,开始执行下轮循环。
这两个关键字可用于for
、while
、until
中。
break
和 continue
后面可以接一个整数(大于 0),即 break N
、continue N
。
这个 N 是什么意思呢?它表示要跳出几层循环,N 默认为 1,即只跳出当前这层循环。例子:
test.sh
1
2
3
4
5
6
7
#!/bin/bash
for ((i = 0; i < 3; i++)); do
for ((j = 0; j < 3; j++)); do
[ "$i" -eq 1 ] && continue 2
echo "$i $j"
done
done
1
2
3
4
5
6
7
$ ./test.sh
0 0
0 1
0 2
2 0
2 1
2 2