Bash 语法
Bash 在 Linux 中是比较常用的脚本语言。本文记录一些有用的 Bash 语法。
特殊符号
Glob 通配符
Glob 通配符是 Linux 中用来匹配文件名的符号。
通配符 | 描述 | 例子 | 匹配 | 不匹配 |
---|---|---|---|---|
* | 匹配任意数量的任何字符,包括无 | Law* | Law, Laws, Lawyer | GrokLaw, La, aw |
? | 匹配任何单个字符 | ?at | Cat, cat, Bat, bat | at |
[abc] | 匹配括号中给出的一个字符 | [CB]at | Cat, Bat | cat, bat |
[a-z] | 匹配括号中给出的范围中的一个字符 | Letter[0-9] | Letter0, Letter1 … Letter9 | Letters, Letter, Letter10 |
[!abc] | 匹配括号中未给出的一个字符 | [!C]at | Bat, bat, cat | Cat |
[!a-z] | 匹配不在括号中给定范围内的一个字符 | Letter[!3-5] | Letter1 … | Letter3 … Letter5, Letterxx |
使用正则匹配
符号 =~
表示通过正则表达式匹配。$1 =~ ^-
表示 $1
参数通过正则表达式 ^-
匹配,并返回匹配结果。若 $1
参数以 -
开头,则返回 true
,否则返回 false
。
定义数组
通过 declare -a array=()
或者 local -a array=()
声明数组变量。
符号 [@]
表示引用数组的所有元素。array[@]
表示数组 array
的所有元素。
获取变量长度
符号 #
表示变量长度。${#array[@]}
表示数组 array
的长度。
参数扩展语法-截取字符
以 local desc=${COMMAND_MAP[$cmd]%%::*}
为例。先声明了一个本地变量 local
,然后通过参数扩展运算符 %%
和 ::*
从数组元素 COMMAND_MAP[$cmd]
中提取字符。
%%
表示从字符串末尾开始删除,直到遇到第一个最长匹配的字符串。::*
是要匹配的模式,表示从 :: 开始一直到末尾的所有字符。组合在一起,就是表示删除从左向右开始,第一个 ::
开头以及后续的所有字符。也就是提取了 COMMAND_MAP[$cmd]
中第一个 ::
之前的字符。
相关的参数扩展运算符:
%
- 从后向前匹配,删除最短匹配的模式%%
- 从后向前匹配,删除最长匹配的模式#
- 从前向后匹配,删除最短匹配的模式##
- 从前向后匹配,删除最长匹配的模式
字符串替换语法-替换字符
以 options_str="${options_str//::/|}"
为例。
Bash 的字符串替换语法,可以分解为:${variable/pattern/string}
- variable: 要操作的变量
- pattern: 要查找的模式
- string: 替换成的新字符串
在这个例子中:
options_str
要操作的变量::
要查找的模式(两个冒号)|
替换成的新字符串(竖线)
前面的 // 表示替换所有匹配。
相关的字符串替换语法:
${var/pattern/string}
- 替换第一个匹配${var//pattern/string}
- 替换所有匹配${var/#pattern/string}
- 替换开头匹配${var/%pattern/string}
- 替换结尾匹配
字段分隔符IFS-分割字符
以IFS="|" read -r desc handler options_str <<< "$info"
为例。可以分解为几个部分:
IFS="|"
:IFS (Internal Field Separator) 是 Bash 的内部字段分隔符,临时将 IFS 设置为竖线|
,这个设置只对这一行命令有效。- read 命令:-r 选项:不让反斜杠转义任何字符,desc handler options_str:三个变量名,用来存储读取的值。
<<< "$info" <<<
是 here string 操作符,将右边的字符串作为输入提供给左边的命令。$info 是源字符串。
条件测试运算符 [[ ]]
符号 [[ ]]
表示条件测试运算符。和 []
的区别是:
- 支持正则表达式匹配 (
=~
) - 支持模式匹配 (
==
) - 支持逻辑运算符 (
&&
,||
) - 不需要对变量值中的空格进行转义
- 防止单词分割(word splitting)
常见用法:
1# 字符串测试2[[ -z $string ]] # 测试字符串是否为空3[[ -n $string ]] # 测试字符串是否非空4[[ $str1 == $str2 ]] # 字符串相等5[[ $str =~ ^- ]] # 正则表达式匹配6
7# 文件测试8[[ -f $file ]] # 是否是普通文件9[[ -d $dir ]] # 是否是目录10[[ -e $path ]] # 是否存在11
12# 数值比较13[[ $a -eq $b ]] # 等于14[[ $a -lt $b ]] # 小于15[[ $a -gt $b ]] # 大于5 collapsed lines
16
17# 逻辑运算18[[ $a && $b ]] # 逻辑与19[[ $a || $b ]] # 逻辑或20[[ ! $a ]] # 逻辑非
逻辑运算符
符号 &&
表示逻辑与运算符。符号 ||
表示逻辑或运算符。符号 !
表示逻辑非运算符。
与条件测试运算符 [[ ]]
结合使用,可以实现复杂的条件判断。例如 [[ -n "${COMMAND_MAP[$cmd]}" ]] || panic "未知命令: $cmd"
表示如果 COMMAND_MAP[$cmd]
为空,则调用 panic
函数,并传入 “未知命令: $cmd” 作为参数。
-n
为测试运算符:检查字符串长度是否非零。如果字符串非空,返回 true,如果字符串为空,返回 false。
||
逻辑或运算符。当左边表达式为 false 时,执行右边的命令,当左边表达式为 true 时,跳过右边的命令。