Shell 测试

简介

程序运行中经常需要根据实际情况来运行特定的命令或代码段。比如,判断某个文件或目录是否存在,如果文件或目录不存在,可能需要首先创建文件或目录。

测试是后续 ifforwhile 结构的判断基础。

测试结构

  • test expression

  • [ expression ]

    推荐使用这种

注意:test是一个外部程序,需要衍生出对应的进程,而[是Bash的一个内部函数,因此后者的执行效率更高。test兼容于Bourne shellashdash

测试的结果是:测试表达式的退出码。

$? 可以返回上条命令的退出码,0表示成功,其他失败。

Bash 扩展

结构:[[ expression ]]

它是一种较新的 bash 机制(2.01 版左右才出现)。能够在 [ ] 中使用的运算符也可用于 [[ ]],但在后者中,等号是一种更为强大的字符串比较运算符。

===,两者在语义上相同。

如果使用了 ==!=,表达式可以是模式匹配

=~ 用于正则表达式匹配。匹配完的结果可在数组 $BASH_REMATCH 中找到。

bash 内建的数组变量 $BASH_REMATCH 的各个元素由括号中的每个子表达式产生。第 0 个元素(${BASH_REMATCH[0]})是正则表达式所匹配的整个字符串。子表达式可以通过 ${BASH_REMATCH[1]}${BASH_REMATCH[2]} 等形式引用。只要将正则表达式写成这样,就会生成变量 $BASH_REMATCH。由于其他bash 函数也许会使用正则表达式进行匹配,因此你可能需要尽快将该变量另存起来,以备后用。

示例

$ ll
total 0
-rw-r--r--  1 takun  staff     0B Mar 31 21:33 a
-rw-r--r--  1 takun  staff     0B Mar 31 21:33 b
-rw-r--r--  1 takun  staff     0B Mar 31 21:33 c

$ test -e a
$ echo $?
0

$ test -e a1
$ echo $?
1

$ [ -e a ]
$ echo $?
0

$ [ -e a1 ]
$ echo $?
1

正则匹配

#
for CDTRACK in *
do
    if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
    then
        echo Track ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]}
        mv "$CDTRACK" "Track${BASH_REMATCH[2]}"
    fi
done

测试符

文件测试符

测试符描述
-e file是否:存在
-d file是否是:目录
-f file是否是:普通文件
-b file是否是:块文件
-c file是否是:字符设备
-L file是否是:连接文件
-S file是否是:socket
-p file是否是:管道
-x file是否:可执行
-w file是否:可写
-r file是否:可读
-s file是否:字节数大于0
-g file是否设置:SGID
-u file是否设置:SUID
-k file是否设置:sticky属性
-G file是否属于:有效的用户组
-O file是否属于:有效的用户
file1 -nt file2是否:file1比file2新
file1 -ot file2是否:file1比file2旧

字符串测试符

测试符描述
-z "string"是否:为空
-n "string"是否:非空
"string1" = "string2"是否:string1和string2相同
"string1" != "string2"是否:string1和string2不相同
"string1" > "string2"是否:string1比string2大,按assci码比较,按字典排序
"string1" < "string2"是否:string1比string2小,按assci码比较,按字典排序

整数测试符

测试符描述
num1 -eq num2是否:相等
num1 -ne num2是否:不相等
num1 -gt num2是否:num1 大于 num2
num1 -lt num2是否:num1 小于 num2
num1 -ge num2是否:num1 大于等于 num2
num1 -le num2是否:num1 小于等于 num2

逻辑运算符

逻辑运算

  • &&:与
  • ||:或
  • ! :非

比如:[ -e x.sh ] && [ -e z.zip ],判断 两个文件都存在。

逻辑测试运算

  • -a:与
  • -o:或
  • ! :非

比如:[ -e x.sh -a -e z.zip ],判断 两个文件都存在。