• 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. Docker Registry 简化版

    目录 Docker Registry 为什么要使用Registry 依赖 启动 Configuring a registry 配置认证 Docker Registry https://docs.doc ...

  2. 三:.net core(.NET 6)给swagger添加文档注释详细步骤

    提供swagger文档注释. 0.先给api加上标题注释和返回值注释: 然后,启动见证奇迹: What the hell?没得注释?查看当前自动生成的swagger代码如下: 首先,我们需要对需要注释 ...

  3. 4D毫米波雷达Radar

    4D毫米波雷达Radar 围绕雷达.激光雷达.高精定位等新一代传感器技术将会进入量产周期. 自动驾驶公司的竞争,在传感器配置上坦白说并没有太多差异化.除了车载激光雷达属于近几年的产物,类似摄像头.毫米 ...

  4. PyTorch 自动微分示例

    PyTorch 自动微分示例 autograd 包是 PyTorch 中所有神经网络的核心.首先简要地介绍,然后训练第一个神经网络.autograd 软件包为 Tensors 上的所有算子提供自动微分 ...

  5. AI芯片体系结构目标图形处理

    AI芯片体系结构目标图形处理 AI chip architecture targets graph processing 可编程图形流处理器(GSP)能够执行"直接图形处理.片上任务图管理和 ...

  6. 采用MVC模式创建一个简单的javascript App

    初次翻译,翻译的不好,还请见谅 JavaScript中最好的一部分之一,也可能是最糟糕的. 在HTML文档的头部添加一个开始和结束脚本标记,并在其中引入一些意大利面条式的代码,毫无疑问这是一种过分简单 ...

  7. 狂神说redis笔记(一)

    一.Nosql概述 1.单机Mysql时代 90年代,一个网站的访问量一般不会太大,单个数据库完全够用.随着用户增多,网站出现以下问题: 数据量增加到一定程度,单机数据库就放不下了 数据的索引(B+ ...

  8. 性能监控之常见 Java Heap Dump 方法

    一.前言 在本文中,我们总结下抓 Java dump 的几种不同方法. Java Heap Dump 是特定时刻 JVM 内存中所有对象的快照.它们对于解决内存泄漏问题和分析 Java 应用程序中的内 ...

  9. 【VBA】最大行,最大列

    最大行: Range("B" & Cells.Rows.Count).End(xlUp).Row 最大列 colu = Range("XFD2").En ...

  10. 【NX二次开发】批量数字签名的方法,解决自己电脑编译的dll在用户正版NX无法使用的问题

    在UG5.0开始,所有开发的DLL都要"签名"后才能被客户端上正版的NX调用. 1. 如果是基于c++开发的dll,使用如下方法可以顺利签名成功(这里借用网上现有的文字和图片) 1 ...