test 是 Shell 内置命令,用来检测某个条件是否成立。test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test。
test 命令有很多选项,可以进行数值、字符串和文件三个方面的检测。
用法
注意点
用法1 test expression
两种用法是等价的,当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值。
用法2 [ expression ]
注意[]
和expression
之间的空格,这两个空格是必须的,否则会导致语法错误
注意,test 只能用来比较整数,小数相关的比较还得依赖 bc 命令。
选 项
作 用
num1 -eq num2
判断 num1 是否和 num2 相等。
num1 -ne num2
判断 num1 是否和 num2 不相等。
num1 -gt num2
判断 num1 是否大于 num2 。
num1 -lt num2
判断 num1 是否小于 num2。
num1 -ge num2
判断 num1 是否大于等于 num2。
num1 -le num2
判断 num1 是否小于等于 num2。
使用(())命令的脚本
使用test命令的脚本
运行结果
注意点
第一次执行
第二次执行
1.test 命令中的变量还是需要加$
2.(())中的变量可以加也可以不加$
3.test中的比较两数值的大小用的是-eq/-gt/-lt等,(())中用的是符号>/</==等
4.[]命令中表达式前后的空格不要忘记!!
选 项
作 用
-z str
判断字符串 str 是否为空。
-n str
判断宇符串 str 是否为非空。
str1 = str2
str1 == str2
=
和==
是等价的,都用来判断 str1 是否和 str2 相等。
str1 != str2
判断 str1 是否和 str2 不相等。
str1 \> str2
判断 str1 是否大于 str2。\>
是>
的转义字符,这样写是为了防止>
被误认为成重定向运算符。
str1 \< str2
判断 str1 是否小于 str2。同样,<
也是转义字符。
注意,==、>、< 在大部分编程语言中都用来比较数字,而在 Shell 中,它们只能用来比较字符串,不能比较数字,这是非常奇葩的。
其次,不管是比较数字还是字符串,Shell 都不支持 >= 和 <= 运算符,切记。
Shell test 字符串比较举例:
脚本
结果
注意点
input str1: aa
input str2:
the strings should not be empty
input str1: aa
input str2: bb
str1<str2
1.判断字符串为空时将变量 $str1 和 $str2 都被双引号包围起来,这样做是为了防止 $str1 或者 $str2 是空字符串时出现错误
2.比较两个字符串时,除了[]中表达式的前后需要空格还要注意str1=str2时,=前后也需要空格!!
文件类型判断
选 项
作 用
-b filename
判断文件是否存在,并且是否为块设备文件。
-c filename
判断文件是否存在,并且是否为字符设备文件。
-d filename
判断文件是否存在,并且是否为目录文件。
-e filename
判断文件是否存在。
-f filename
判断文件是否存在,井且是否为普通文件。
-L filename
判断文件是否存在,并且是否为符号链接文件。
-p filename
判断文件是否存在,并且是否为管道文件。
-s filename
判断文件是否存在,并且是否为非空。
-S filename
判断该文件是否存在,并且是否为套接字文件。
文件权限判断
选 项
作 用
-r filename
判断文件是否存在,并且是否拥有读权限。
-w filename
判断文件是否存在,并且是否拥有写权限。
-x filename
判断文件是否存在,并且是否拥有执行权限。
-u filename
判断文件是否存在,并且是否拥有 SUID 权限。
-g filename
判断文件是否存在,并且是否拥有 SGID 权限。
-k filename
判断该文件是否存在,并且是否拥有 SBIT 权限。
文件比较
选 项
作 用
filename1 -nt filename2
判断 filename1 的修改时间是否比 filename2 的新。
filename -ot filename2
判断 filename1 的修改时间是否比 filename2 的旧。
filename1 -ef filename2
判断 filename1 是否和 filename2 的 inode 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法
脚本
结果
注意点
input filename1: aa
imput filename2:
the input is empty
input filename1: aa
imput filename2: bb
please input exist file
touch aaa
input filename1: aaa
imput filename2: /data/1learn_linux/
please input not empty file
input filename1: /data/1learn_linux/
imput filename2: /data/1learn_linux/learn_test_str.sh
please input filename, not dir
input filename1: /data/1learn_linux/learn_test_str.sh
imput filename2: /data/1learn_linux/learn_test.sh
file1 new file2
1.空格
2.逻辑非要放在表达式前边,例如 [ ! -e "$filename1" ]
-e "$filename1"代表的是文件存在的情况
! -e "$filename1"代表的是文件不存在时的情况
选 项
作 用
expression1 -a expression
逻辑与,表达式 expression1 和 expression2 都成立,最终的结果才是成立的。
expression1 -o expression2
逻辑或,表达式 expression1 和 expression2 有一个成立,最终的结果就成立。
!expression
逻辑非,对 expression 进行取反。
改写上面的代码,使用逻辑运算选项:
脚本
结果
注意点
input filename1: aa
imput filename2: bb
please input exist file
input filename1: /data/1learn_linux/
imput filename2: aa
please input exist file
1.逻辑非!与-o混用时,注意!只起作用于当前表达式,不是-o链接起来的整个表达式
2.使用-o,将两个[]合为1个
假设 test 命令对应的函数是 func(),使用test -z $str1
命令时,会先将变量 $str1 替换成字符串:
test -z abc123
,调用 func() 函数的形式就是func("-z abc123")
。test 命令后面附带的所有选项和参数会被看成一个整体,并作为实参传递进函数。test -z
,调用 func() 函数的形式就是func("-z ")
,这就比较奇怪了,因为-z
选项没有和参数成对出现,func() 在分析时就会出错。如果我们给 $str1 变量加上双引号,当 $str1 是空字符串时,test -z "$str1"
就会被替换为test -z ""
,调用 func() 函数的形式就是func("-z \"\"")
,很显然,-z
选项后面跟的是一个空字符串(\"
表示转义字符),这样 func() 在分析时就不会出错了。
所以,当在 test 命令中使用变量时,强烈建议将变量用双引号""
包围起来,这样能避免变量为空值时导致的很多奇葩问题。
test 命令比较奇葩,>、<、== 只能用来比较字符串,不能用来比较数字,比较数字需要使用 -eq、-gt 等选项;不管是比较字符串还是数字,test 都不支持 >= 和 <=。
对于整型数字的比较,建议使用 (()),(()) 支持各种运算符,写法也符合数学规则,用起来更加方便
手机扫一扫
移动阅读更方便
你可能感兴趣的文章