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 时,跳过右边的命令。