shell中test命令的用法详解

1. test命令

test 是 Shell 内置命令,用来检测某个条件是否成立。test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test。
test 命令有很多选项,可以进行数值、字符串和文件三个方面的检测。

Shell test 命令的用法为:
test expression
当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值

test 命令也可以简写为[],它的用法为:[ expression ]
eg:
注意[]expression之间的空格,这两个空格是必须的,否则会导致语法错误。[]的写法更加简洁,比 test 使用频率高

#!/bin/bash
read age
if test $age -le 2; then
    echo "婴儿"
elif test $age -ge 3 && test $age -le 8; then
    echo "幼儿"
elif [ $age -ge 9 ] && [ $age -le 17 ]; then
    echo "少年"
elif [ $age -ge 18 ] && [ $age -le 25 ]; then
    echo "成年"
elif test $age -ge 26 && test $age -le 40; then
    echo "青年"
elif test $age -ge 41 && [ $age -le 60 ]; then
    echo "中年"
else
    echo "老年"
fi

#其中,-le选项表示小于等于,-ge选项表示大于等于,&&是逻辑与运算符

2. 与文件检测相关的 test 选项

文件类型判断

-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 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法

Shell 中test 文件检测举例

test.sh

#!/bin/bash
read filename
read url
if test -w $filename && test -n $url
then
    echo $url > $filename
    echo "写入成功"
else
    echo "写入失败"
fi

测试结果:

[root@server1 mnt]# touch dd
[root@server1 mnt]# sh test.sh 
dd
westos.org
写入成功
[root@server1 mnt]# cat dd 
westos.org

3.与数值比较相关的 test 选项

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 只能用来比较整数,小数相关的比较还得依赖 bc 命令

eg:test.sh

#!/bin/bash
read a b
if test $a -eq $b
then
    echo "两个数相等"
else
    echo "两个数不相等"
fi

测试结果:

[root@server1 mnt]# sh test.sh 
2 3
两个数不相等

4.与字符串判断相关的 test 选项

z str判断字符串 str 是否为空
-n str判断宇符串 str 是否为非空
str1 = str2与str1 == str2=和==是等价的,都用来判断 str1 是否和 str2 相等。
str1 != str2判断 str1 是否和 str2 不相等。
str1 \> str2判断 str1 是否大于 str2。\>>的转义字符,这样写是为了防止>被误认为成重定向运算符。
str1 \< str2判断 str1 是否小于 str2。同样,\<也是转义字符

注意:
#有C语言、C++、Python、Java 等编程经验的读者请注意,==、>、< 在大部分编程语言中都用来比较数字,而在 Shell 中,它们 只能用来比较字符串,不能比较数字,这是非常奇葩的,大家要习惯
#其次,不管是比较数字还是字符串,Shell 都不支持 >= 和 <= 运算符,切记

eg: test.sh

#!/bin/bash
read str1
read str2
#检测字符串是否为空
if [ -z "$str1" ] || [ -z "$str2" ]
then
    echo "字符串不能为空"
    exit 0
fi
#比较字符串
if [ $str1 = $str2 ]
then
    echo "两个字符串相等"
else
    echo "两个字符串不相等"
fi

#变量 $str1 和 $str2 都被双引号包围起来,这样做是为了防止 $str1 或者 $str2 是空字符串时出现错误

测试:

[root@server1 mnt]# sh test.sh 


字符串不能为空
[root@server1 mnt]# sh test.sh 
1

字符串不能为空
[root@server1 mnt]# sh test.sh 

2
字符串不能为空
[root@server1 mnt]# sh test.sh 
redhat
redhat
两个字符串相等
[root@server1 mnt]# sh test.sh 
redhat
shell
两个字符串不相等

5.与逻辑运算相关的 test 选项

expression1 -a expression 逻辑与,表达式 expression1 和 expression2 都成立,最终的结果才是成立的。

expression1 -o expression2 逻辑或,表达式 expression1 和 expression2 有一个成立,最终的结果就成立。

!expression 逻辑非,对 expression 进行取反

改写上面的代码,使用逻辑运算选项

[root@server1 mnt]# cat test.sh 
#!/bin/bash
read str1
read str2
#检测字符串是否为空
if [ -z "$str1" -o -z "$str2" ]  #使用 -o 选项取代之前的 ||
then
    echo "字符串不能为空"
    exit 0
fi
#比较字符串
if [ $str1 = $str2 ]
then
    echo "两个字符串相等"
else
    echo "两个字符串不相等"
fi

#前面的代码我们使用两个[]命令,并使用||运算符将它们连接起来,这里我们改成-o选项,只使用一个[]命令就可以了

在 test 中使用变量建议用双引号包围起来
test 和 [] 都是命令,一个命令本质上对应一个程序或者一个函数。=

假设 test 命令对应的函数是 func(),使用test -z $str1命令时,会先将变量 $str1 替换成字符串:

如果 $str1 是一个正常的字符串,比如 abc123,那么替换后的效果就是test -z abc123,调用 func() 函数的形式就是func("-z abc123")。test 命令后面附带的所有选项和参数会被看成一个整体,并作为实参传递进函数。
如果 $str1 是一个空字符串,那么替换后的效果就是test -z ,调用 func() 函数的形式就是func("-z "),这就比较奇怪了,因为-z选项没有和参数成对出现,func() 在分析时就会出错。

如果我们给 $str1 变量加上双引号,当 s t r 1 是 空 字 符 串 时 , t e s t − z " str1 是空字符串时,test -z " str1testz"str1"就会被替换为test -z “”,调用 func() 函数的形式就是func("-z " “”),很显然,-z选项后面跟的是一个空字符串(\“表示转义字符),这样 func() 在分析时就不会出错了
“””
总结:
test 命令比较奇葩,>、<、== 只能用来比较字符串,不能用来比较数字,比较数字需要使用 -eq、-gt 等选项;不管是比较字符串还是数字,test 都不支持 >= 和 <=。有经验的程序员需要慢慢习惯 test 命令的这些奇葩用法。

对于整型数字的比较,我建议大家使用 (()),(()) 支持各种运算符,写法也符合数学规则,用起来更加方便

`test` 命令也可以用方括号 `[ ]` 的形式来执行,这两种形式是等价的。`test` 命令用于测试文件、字符串和数值等各种条件,返回一个布尔值(0 表示 true,1 表示 false)。下面是 `test` 命令的一些常用选项和用法: 1. 检查文件 - `-e file`:如果文件存在,则返回 true - `-f file`:如果文件存在且是一个普通文件,则返回 true - `-d file`:如果文件存在且是一个目录,则返回 true - `-r file`:如果文件存在且可读,则返回 true - `-w file`:如果文件存在且可写,则返回 true - `-x file`:如果文件存在且可执行,则返回 true - `-s file`:如果文件存在且非空,则返回 true - `file1 -nt file2`:如果文件 `file1` 比文件 `file2` 新,则返回 true - `file1 -ot file2`:如果文件 `file1` 比文件 `file2` 旧,则返回 true 2. 检查字符串 - `-z string`:如果字符串为空,则返回 true - `-n string`:如果字符串非空,则返回 true - `string1 = string2`:如果字符串 `string1` 等于字符串 `string2`,则返回 true - `string1 != string2`:如果字符串 `string1` 不等于字符串 `string2`,则返回 true 3. 检查数值 - `num1 -eq num2`:如果数值 `num1` 等于数值 `num2`,则返回 true - `num1 -ne num2`:如果数值 `num1` 不等于数值 `num2`,则返回 true - `num1 -lt num2`:如果数值 `num1` 小于数值 `num2`,则返回 true - `num1 -le num2`:如果数值 `num1` 小于或等于数值 `num2`,则返回 true - `num1 -gt num2`:如果数值 `num1` 大于数值 `num2`,则返回 true - `num1 -ge num2`:如果数值 `num1` 大于或等于数值 `num2`,则返回 true 以上只是 `test` 命令的一些常见用法,还有很多其他的选项和用法,可以通过 `man test` 命令查看完整的帮助文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值