Shell test命令(Shell [])详解,附带所有选项及说明
test 是 Shell 内置命令,用来检测某个条件是否成立。test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test。
test 命令有很多选项,可以进行数值、字符串和文件三个方面的检测。
Shell test 命令的用法为:
test expression
当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值。
test 命令也可以简写为[]
,它的用法为:
[ expression ]
注意[]
和expression
之间的空格,这两个空格是必须的,否则会导致语法错误。[]
的写法更加简洁,比 test 使用频率高。
test 和 [] 是等价的,后续我们会交替使用 test 和 [],以让读者尽快熟悉。
在《Shell if else》中,我们使用 (()) 进行数值比较,这节我们就来看一下如何使用 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
选项表示大于等于,&&
是逻辑与运算符。
学习 test 命令,重点是学习它的各种选项,下面我们就逐一讲解。
1) 与文件检测相关的 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 文件检测举例:
- #!/bin/bash
- read filename
- read url
- if test -w $filename && test -n $url
- then
- echo $url > $filename
- echo "写入成功"
- else
- echo "写入失败"
- fi
在 Shell 脚本文件所在的目录新建一个文本文件并命名为 urls.txt,然后运行 Shell 脚本,运行结果为:
urls.txt↙
http://c.biancheng.net/shell/↙
写入成功
2) 与数值比较相关的 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 命令。
Shell test 数值比较举例:
- #!/bin/bash
- read a b
- if test $a -eq $b
- then
- echo "两个数相等"
- else
- echo "两个数不相等"
- fi
运行结果1:
10 10
两个数相等
运行结果2:
10 20
两个数不相等
3) 与字符串判断相关的 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 都不支持 >= 和 <= 运算符,切记。
Shell test 字符串比较举例:
- #!/bin/bash
- read str1
- read str2
- #检测字符串是否为空
- if [ -z "$str1" ] || [ -z "$str2" ]
- then
- echo "字符串不能为空"
- exit 0
- fi
- #比较字符串
- if [ $str1 = $str2 ]
- then
- echo "两个字符串相等"
- else
- echo "两个字符串不相等"
- fi
运行结果:
http://c.biancheng.net/
http://c.biancheng.net/shell/
两个字符串不相等
细心的读者可能已经注意到,变量 $str1 和 $str2 都被双引号包围起来,这样做是为了防止 $str1 或者 $str2 是空字符串时出现错误,本文的后续部分将为你分析具体原因。
4) 与逻辑运算相关的 test 选项
选 项 | 作 用 |
---|---|
expression1 -a expression | 逻辑与,表达式 expression1 和 expression2 都成立,最终的结果才是成立的。 |
expression1 -o expression2 | 逻辑或,表达式 expression1 和 expression2 有一个成立,最终的结果就成立。 |
!expression | 逻辑非,对 expression 进行取反。 |
改写上面的代码,使用逻辑运算选项:
- #!/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 和 [] 都是命令,一个命令本质上对应一个程序或者一个函数。即使是一个程序,它也有入口函数,例如C语言程序的入口函数是 main(),运行C语言程序就从 main() 函数开始,所以也可以将一个程序等效为一个函数,这样我们就不用再区分函数和程序了,直接将一个命令和一个函数对应起来即可。
有了以上认知,就很容易看透命令的本质了:使用一个命令其实就是调用一个函数,命令后面附带的选项和参数最终都会作为实参传递给函数。
假设 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 变量加上双引号,当 $str1 是空字符串时,test -z "$str1"
就会被替换为test -z ""
,调用 func() 函数的形式就是func("-z \"\"")
,很显然,-z
选项后面跟的是一个空字符串(\"
表示转义字符),这样 func() 在分析时就不会出错了。
所以,当你在 test 命令中使用变量时,我强烈建议将变量用双引号""
包围起来,这样能避免变量为空值时导致的很多奇葩问题。
总结
test 命令比较奇葩,>、<、== 只能用来比较字符串,不能用来比较数字,比较数字需要使用 -eq、-gt 等选项;不管是比较字符串还是数字,test 都不支持 >= 和 <=。有经验的程序员需要慢慢习惯 test 命令的这些奇葩用法。
对于整型数字的比较,我建议大家使用 (()),这在《Shell if else》中已经进行了演示。(()) 支持各种运算符,写法也符合数学规则,用起来更加方便,何乐而不为呢?
几乎完全兼容 test ,并且比 test 更加强大,比 test 更加灵活的是[[ ]]
;[[ ]]
不是命令,而是 Shell 关键字,下节《Shell [[]]》我们将会讲解
Shell test命令(Shell [])详解,附带所有选项及说明
转载于:https://www.cnblogs.com/qiangyuzhou/p/10806667.html
Shell test命令(Shell [])详解,附带所有选项及说明相关推荐
- Linux shell test命令用法详解
test命令用法.功能:检查文件和比较值 1)判断表达式 if test (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2 两个表达式都为真 test 表达式1 –o ...
- Shell常用命令-- seq 详解
一.seq命令 seq: 是一个序列(squeue )的缩写,主要用来输出序列化的东西 用法: seq [选项]- 尾数 #从到尾数 seq [选项]- 首数 尾数 #从首数到尾数 seq [选项]- ...
- Linux Shell脚本入门--wget 命令用法详解
Linux Shell脚本入门--wget 命令用法详解 wget是在Linux下开发的开放源代码的软件,作者是Hrvoje Niksic,后来被移植到包括Windows在内的各个平台上.它有以下功能 ...
- shell编程系列23--shell操作数据库实战之mysql命令参数详解
shell编程系列23--shell操作数据库实战之mysql命令参数详解mysql命令参数详解-u 用户名-p 用户密码-h 服务器ip地址-D 连接的数据库-N 不输出列信息-B 使用tab键代替 ...
- linux shell 端口占用,linux 查看端口占用命令实例详解
linux 查看端口占用命令实例详解 端口是系统非常重要的一个东东,我们经常需要查看哪个进程占用了哪个端口,或者哪个端口被哪个进程占用.废话不多说,直接上干货,教大家怎样查看系统端口占用情况. 方法一 ...
- 11. shell当中read详解,read语法选项,read用法示例,脚本示例,while read line详解,掌握原则
shell当中read详解,read语法选项,read用法示例,脚本示例,while read line详解,掌握原则 文章目录 1.1 read详解 1.2 用法示例 1.3 while read ...
- php mysql source_Mysql数据库导入命令Source详解
Mysql数据库导入命令Source详解 几个常用用例: 1.导出整个数据库 mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldump -u root -p data ...
- linux中cat、more、less命令区别详解
linux中cat.more.less命令区别详解 转自:https://blog.csdn.net/xyw_blog/article/details/16861681 众所周知linux中命令cat ...
- Linux下Grub命令配置详解
grub(Grand Unified Boot Loader)启动引导器 与grub相似软件比较 BM:安装多操作系统软件,必须把两个操作系统安装在主分区,硬盘最多可以分4个主分区. LILO:以前l ...
- chmod命令使用详解
文件/目录权限设置命令 chmod 文件/目录权限设置命令:chmod 这是Linux系统管理员最常用到的命令之一,它用于改变文件或目录的访问权限.该命令有两种用法: 用包含字母和操作符表达式的文字设 ...
最新文章
- 机器学习特征工程之连续变量离散化:等宽分箱
- Linux Unix C 中的curses库——curses.h
- mysql数据库运行远程用户访问不了_MySQL数据库远程访问权限如何打开(两种方法)...
- 在 Docker 里运行 Microsoft SQL 服务器
- shutil.rmtree()
- 轻松创建nodejs服务器(1):一个简单nodejs服务器例子
- Android(1)—Mono For Android 环境搭建及破解
- 拼多多开始卖车了!3.49万秒杀五菱宏光...
- javaSE----学习路线
- python进行谱曲_python进行曲——迭代生成
- servlet 从oracle中结果集,用servlet对oracle进行增删改查
- linux命令行启动向日葵无法编辑,向日葵linux版无法启动
- java离线地图web
- 计算机出现蓝屏怎么恢复,重启电脑后出现蓝屏怎么办
- Python html.parser库学习小结
- 从学员角度体验教练技术之考驾照
- 从Anker到SHEIN,对不起我要放弃Amazon了
- matlab绘制共用x轴图像 subplot子图不显示问题
- Centos 7 新版安装mysql
- 基于SSM搭建的学生信息管理系统项目源码+学习视频
热门文章
- CloudStack那些事儿2 : 主存储与二级存储
- 高斯赛德尔迭代c语言_逐次超松弛SOR迭代概述
- acwing yxc总结时间算法复杂度
- 对面向对象设计原则的总结
- Codeforces Round #539 (Div. 1)
- 入门一班 20181024 io监控free ps 网络状态 抓包
- Python3爬虫-01-简单网页爬取
- RabbitMQ学习总结(4)——分发任务在多个工作者之间实例教程
- CodeLobster PHP Edition v4.5.3 Professional 注册码
- [C# 开发技巧系列] 使用C#操作幻灯片