• 0.test命令的用法
  • 1.与数值比较相关的test选项
  • 2.与字符串判断相关的 test 选项
  • 3.与文件检测相关的test选项
  • 4.与逻辑运算相关的test选项
  • 5.注意点与总结
    • 1.test中变量用双引号包围起来
    • 2.总结

test 是 Shell 内置命令,用来检测某个条件是否成立。test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test。

test 命令有很多选项,可以进行数值、字符串和文件三个方面的检测。

0.test命令的用法

用法 注意点  
用法1 test expression   两种用法是等价的,当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值。
用法2 [ expression ] 注意[]expression之间的空格,这两个空格是必须的,否则会导致语法错误

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

注意,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. #!/bin/bash
  2. read -p 'please input num1: ' num1
  3. read -p 'please input num2: ' num2
  4. if (($num1==$num2))
  5. then
  6. echo 'the num is equal'
  7. elif ((num1>num2))
  8. then
  9. echo 'the num1 is large than num2'
  10. else
  11. echo 'the num1 is small num2'
  12. fi
  1. #!/bin/bash
  2. read -p 'please input num1: ' num1
  3. read -p 'please input num2: ' num2
  4. if test $num1 -eq $num2
  5. then
  6. echo 'the num is equal'
  7. elif [ $num1 -gt $num2 ]
  8. then
  9. echo 'the num1 is large than num2'
  10. else
  11. echo 'the num1 is small num2'
  12. fi

第一次执行

  1. please input num1: 10
  2. please input num2: 10
  3. the num is equal

第二次执行

  1. please input num1: 4
  2. please input num2: 6
  3. the num1 is small num2

1.test 命令中的变量还是需要加$

2.(())中的变量可以加也可以不加$

3.test中的比较两数值的大小用的是-eq/-gt/-lt等,(())中用的是符号>/</==等

4.[]命令中表达式前后的空格不要忘记!!

2.与字符串判断相关的 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。同样,\<也是转义字符。

注意,==、>、< 在大部分编程语言中都用来比较数字,而在 Shell 中,它们只能用来比较字符串,不能比较数字,这是非常奇葩的。
其次,不管是比较数字还是字符串,Shell 都不支持 >= 和 <= 运算符,切记。

Shell test 字符串比较举例:

脚本
结果
注意点
  1. #!/bin/bash
  2. read -p 'input str1: ' str1
  3. read -p 'input str2: ' str2
  4. if [ -z "$str1" ]||[ -z "$str2" ]
  5. then echo 'the strings should not be empty'
  6. elif [ $str1 = $str2 ]
  7. then echo 'str1=str2'
  8. elif [ $str1 \> $str2 ]
  9. then echo 'str1 > str2'
  10. elif [ $str1 \< $str2 ]
  11. then echo 'str1<str2'
  12. fi
  1. input str1: aa
  2. input str2:
  3. the strings should not be empty
  1. input str1: aa
  2. input str2: bb
  3. str1<str2
  1. input str1: aa
  2. input str2: aa
  3. str1=str2
  1. input str1: bb
  2. input str2: a
  3. str1 > str2

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

2.比较两个字符串时,除了[]中表达式的前后需要空格还要注意str1=str2时,=前后也需要空格!!

3.与文件检测相关的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 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法
脚本
结果
注意点
  1. #!/bin/bash
  2. read -p 'input filename1: ' filename1
  3. read -p 'imput filename2: ' filename2
  4. if [ -z "$filename1" ]||[ -z "$filename2" ];#判断输入值是否为空
  5. then echo 'the input is  empty'
  6. elif [ ! -e "$filename1" ]||[ -e "$filename2" ];#判断输入文件是否存在,如果不存在提示并退出
  7. then echo 'please input exist file'
  8. exit 2
  9. elif [ -s "$filename1" ]||[ -s "$filename2" ];#判断输入文件是否为空,为空则提示退出
  10. then echo 'please input not empty file'
  11. exit 2
  12. elif [ -d "$filename1" ]||[ -d "$filename2" ];#判断输入文件是否为目录,是则提示退出
  13. then echo 'please input filename, not dir'
  14. exit 2
  15. elif [ $filename1 -nt $filename2 ];#判断文件新旧
  16. then echo 'file1 new file2'
  17. elif [ $filename1 -ot $filename2 ];#判断文件新旧
  18. then echo 'file1 old file2'
  19. elif [ $filename1 -ef $filename2 ];#判断文件是否相同
  20. then echo 'file1 equal file2'
  21. else
  22. echo 'some error'
  23. fi
  1. input filename1: aa
  2. imput filename2:
  3. the input is empty
  1. input filename1: aa
  2. imput filename2: bb
  3. please input exist file
  1. touch aaa
  2. input filename1: aaa
  3. imput filename2: /data/1learn_linux/
  4. please input not empty file
  1. input filename1: /data/1learn_linux/
  2. imput filename2: /data/1learn_linux/learn_test_str.sh
  3. please input filename, not dir
  1. input filename1: /data/1learn_linux/learn_test_str.sh
  2. imput filename2: /data/1learn_linux/learn_test.sh
  3. file1 new file2
  1. input filename1: /data/1learn_linux/learn_test.sh
  2. imput filename2: /data/1learn_linux/learn_test_str.sh
  3. file1 old file2
  1. input filename1: /data/1learn_linux/learn_test.sh
  2. imput filename2: /data/1learn_linux/learn_test.sh
  3. file1 equal file2

1.空格

2.逻辑非要放在表达式前边,例如 [ ! -e "$filename1" ]

-e "$filename1"代表的是文件存在的情况

! -e "$filename1"代表的是文件不存在时的情况

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

选 项
作 用
expression1 -a expression 逻辑与,表达式 expression1 和 expression2 都成立,最终的结果才是成立的。
expression1 -o expression2 逻辑或,表达式 expression1 和 expression2 有一个成立,最终的结果就成立。
!expression 逻辑非,对 expression 进行取反。

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

脚本
结果
注意点
  1. #!/bin/bash
  2. read -p 'input filename1: ' filename1
  3. read -p 'imput filename2: ' filename2
  4. if [ -z "$filename1" -o -z "$filename2" ];#判断输入值是否为空
  5. then echo 'the input is  empty'
  6. elif [ ! -e "$filename1" -o -e "$filename2" ];#判断输入文件是否存在,如果不存在提示并退出
  7. then echo 'please input exist file'
  8. exit 2
  9. else
  10. echo 'files exist'
  11. fi
  1. input filename1: aa
  2. imput filename2: bb
  3. please input exist file
  1. input filename1: /data/1learn_linux/
  2. imput filename2: aa
  3. please input exist file
  1. input filename1: aa
  2. imput filename2: /data/1learn_linux/
  3. please input exist file
  1. input filename1: /data/1learn_linux/
  2. imput filename2: /data/1learn_linux/
  3. files exist

1.逻辑非!与-o混用时,注意!只起作用于当前表达式,不是-o链接起来的整个表达式

2.使用-o,将两个[]合为1个

5.注意点与总结

1.test中变量用双引号包围起来

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

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

如果我们给 $str1 变量加上双引号,当 $str1 是空字符串时,test -z "$str1"就会被替换为test -z "",调用 func() 函数的形式就是func("-z \"\""),很显然,-z选项后面跟的是一个空字符串(\"表示转义字符),这样 func() 在分析时就不会出错了。

所以,当在 test 命令中使用变量时,强烈建议将变量用双引号""包围起来,这样能避免变量为空值时导致的很多奇葩问题。

2.总结

test 命令比较奇葩,>、<、== 只能用来比较字符串,不能用来比较数字,比较数字需要使用 -eq、-gt 等选项;不管是比较字符串还是数字,test 都不支持 >= 和 <=。
对于整型数字的比较,建议使用 (()),(()) 支持各种运算符,写法也符合数学规则,用起来更加方便

10 shell test命令的更多相关文章

  1. Linux编程 10 (shell外部命令与内建命令,alias ,type命令)

    一.  内部命令 Linux命令有内部命令(内建命令)和外部命令之分,内部命令和外部命令功能基本相同,但也有些细微差别.内部命令不需要使用子进程来执行,它们已经和shell编译成一体,作为shell工 ...

  2. Windows 10 Shell命令

    可以在[win+R] run 窗口 和 explorer窗口中使用 在command prompt中使用: C:\Users\a>explorer shell:sendto “ shell:Ac ...

  3. linux 学习10 shell 基础

    10.1 Shell概述 .Shell是什么 Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动.挂起.停止甚至是编写一 ...

  4. linux 基础 shell脚本命令

    #########shell脚本命令#### 1.diff diff file file1 ####比较两个文件的不同 -c ####显示周围的行 -u ####按照一格式统一输出生成补丁 -r ## ...

  5. Linux基本命令(10)其他命令

    其他命令 命令 功能 命令 功能 echo 显示一字串 passwd 修改密码 clear 清除显示器 lpr 打印 lpq 查看在打印队列中等待的作业 lprm 取消打印队列中的作业 10.1 ec ...

  6. Shell printf 命令

    Shell printf 命令 printf 命令模仿 C 程序库(library)里的 printf() 程序. 标准所定义,因此使用printf的脚本比使用echo移植性好. printf 使用引 ...

  7. Linux从入门到进阶全集——【第十四集:Shell基础命令】

    1,Shell就是命令行执行器 2,作用:将外层引用程序的例如ls ll等命令进行解释成01表示的二进制代码给内核,从而让硬件执行:硬件的执行结果返回给shell,shell解释成我们能看得懂的代码返 ...

  8. shell重定向命令执行顺序

    重定向内容介绍 一条shell命令的执行包含三个文件描述符:标准输入(键盘等) stdin 0,标准正确输出(屏幕等) stdout 1,标准错误输出(屏幕等)stderr 2   通过重定向可以指定 ...

  9. Shell 常用命令总结

      Shell常用命令总结 1  ls命令:列出文件 ls -la 列出当前目录下的所有文件和文件夹 ls a* 列出当前目录下所有以a字母开头的文件 ls -l *.txt 列出当前目录下所有后缀名 ...

随机推荐

  1. C++的构造函数为何不能为虚函数

    1. 存储空间角度:虚函数对应一个vtable,vtable存储于对象的内存空间 若构造函数是虚的,则需要通过 vtable来调用,若对象还未实例化,即内存空间还没有,无法找到vtable 2. 使用 ...

  2. Linux系统函数read()/write()/pread()/pwrite()的区别-(转自CSDN网络)

    在Linux和UNIX中有很多的输入输出函数,有时真是让想跟它攀点关系的菜鸟们束手无策.先来看看都有哪些函数,通过解析与总结,看看能不能让大家能这些函数有个理性的认识,哦,原来是这么回事,也就算我没白 ...

  3. Java中生成唯一标识符的方法(Day_48)

    有时候业务需要生成唯一标识符,但又不能依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,此时我们就需要用程序来生成一个唯一的全局ID. UUID UUID是指在一台机器上 ...

  4. android常用的四种对话框java代码

    AlterDialog:确认取消警告提示框 public void showAlertDialog(View view){ AlertDialog.Builder dialog = new Alert ...

  5. 【JVM进阶之路】十四:类加载器和类加载机制

    在上一章里,我们已经学习了类加载的过程,我们知道在加载阶段需要"通过一个类的全限定名来获取描述该类的二进制字节流",而来完成这个工作的就是类加载器(Class Loader). 1 ...

  6. 『动善时』JMeter基础 — 31、JMeter中BeanShell断言详解

    目录 1.BeanShell简介 2.Beanshell的内置变量和方法 3.BeanShell断言界面详解 4.BeanShell断言的使用 (1)测试计划内包含的元件 (2)登陆接口请求界面内容 ...

  7. 【NX二次开发】按层查找工作部件中的对象 UF_LAYER_cycle_by_layer

    第一次调用 :返回第一个启用层中的第一个对象. 第二次调用 :返回下一个已启用层中的下一个对象. 最后一次调用:当所有对象都被耗尽时,将返回object_tag = NULL_TAG. 在循环数据库时 ...

  8. 使用 Hexo 搭建静态博客

    目录 Hexo 简介 什么是 Hexo? Hexo 安装 Hexo 建站 Hexo 配置 Hexo 自定义主题 Hexo 写作 Hexo 服务器 Hexo 生成与发布 一键部署 Hexo 站点到 gi ...

  9. ES6中的字符串

    字符串在编程语言中,一直是使用率很高的数据,虽说函数在js语言中是一等公民,但是字符串,怎么也能算得上是千年老二,下面我就一起和大家探讨一下在es6中的一些新用法和特性,特别是在字符串拼接的时候,会解 ...

  10. Spring Boot WebFlux-导读

    背景 大家都知道,Spring Framework 是 Java/Spring 应用程序跨平台开发框架,也是 Java EE(Java Enterprise Edition) 轻量级框架,其 Spri ...