判断表达式

使用 test 判断

1. test 基本用法

# 写法一 (不支持正则判断)
test expression

# 写法二(不支持正则判断)
[ expression ]

# 写法三 (支持正则判断)
[[ expression ]]

2. 文件判断

  • [ -a file ]:如果 file 存在,则为true
  • [ -b file ]:如果 file 存在并且是一个块(设备)文件,则为true
  • [ -c file ]:如果 file 存在并且是一个字符(设备)文件,则为true
  • [ -d file ]:如果 file 存在并且是一个目录,则为true
  • [ -e file ]:如果 file 存在,则为true
  • [ -f file ]:如果 file 存在并且是一个普通文件,则为true
  • [ -g file ]:如果 file 存在并且设置了组 ID,则为true
  • [ -G file ]:如果 file 存在并且属于有效的组 ID,则为true
  • [ -h file ]:如果 file 存在并且是符号链接,则为true
  • [ -k file ]:如果 file 存在并且设置了它的“sticky bit”,则为true
  • [ -L file ]:如果 file 存在并且是一个符号链接,则为true
  • [ -N file ]:如果 file 存在并且自上次读取后已被修改,则为true
  • [ -O file ]:如果 file 存在并且属于有效的用户 ID,则为true
  • [ -p file ]:如果 file 存在并且是一个命名管道,则为true
  • [ -r file ]:如果 file 存在并且可读(当前用户有可读权限),则为true
  • [ -s file ]:如果 file 存在且其长度大于零,则为true
  • [ -S file ]:如果 file 存在且是一个网络 socket,则为true
  • [ -t fd ]:如果 fd 是一个文件描述符,并且重定向到终端,则为true。用于判断是否重定向了标准输入/输出/错误。
  • [ -u file ]:如果 file 存在并且设置了 setuid 位,则为true
  • [ -w file ]:如果 file 存在并且可写(当前用户拥有可写权限),则为true
  • [ -x file ]:如果 file 存在并且可执行(有效用户有执行/搜索权限),则为true
  • [ file1 -nt file2 ]:如果 FILE1 比 FILE2 的更新时间最近,或者 FILE1 存在而 FILE2 不存在,则为true
  • [ file1 -ot file2 ]:如果 FILE1 比 FILE2 的更新时间更旧,或者 FILE2 存在而 FILE1 不存在,则为true
  • [ FILE1 -ef FILE2 ]:如果 FILE1 和 FILE2 引用相同的设备和 inode 编号,则为true

3. 字符串判断(==

  • [ string ]:如果string不为空(长度大于0),则判断为真。
  • [ -n string ]:如果字符串string的长度大于零,则判断为真。
  • [ -z string ]:如果字符串string的长度为零,则判断为真。
  • [ string1 = string2 ]:如果string1string2相同,则判断为真。
  • [ string1 == string2 ] 等同于[ string1 = string2 ]
  • [ string1 != string2 ]:如果string1string2不相同,则判断为真。
  • [ string1 '>' string2 ]:如果按照字典顺序string1排列在string2之后,则判断为真。
  • [ string1 '<' string2 ]:如果按照字典顺序string1排列在string2之前,则判断为真。

注意,test命令内部的><,必须用引号引起来(或者是用反斜杠转义)。否则,它们会被 shell 解释为重定向操作符。

4. 整数判断(-eq

  • [ n1 -eq n2 ]:如果n1等于n2,则为true
  • [ n1 -ne n2 ]:如果n1不等于n2,则为true
  • [ n1 -le n2 ]:如果n1小于或等于n2,则为true
  • [ n1 -lt n2 ]:如果n1小于n2,则为true
  • [ n1 -ge n2 ]:如果n1大于或等于n2,则为true
  • [ n1 -gt n2 ]:如果n1大于n2,则为true

5. 正则判断(=~

#!/bin/bash

INT=-5

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
  echo "INT is an integer."
  exit 0
else
  echo "INT is not an integer." >&2
  exit 1
fi

多条件逻辑运算

  • AND运算:符号&&,也可使用参数-a
  • OR运算:符号||,也可使用参数-o
  • NOT运算:符号!

通过 ((...)) 进行算术运算判断

if ((3 > 2)); then
  echo "true"
fi

if 配套 test((...)) 进行条件判断

项目 bash csh
if if [ -f $a ];then
echo “hello world!”
fi
if(expression)then
commands
endif
if {(command)} then
commands
endif
if(expression) then
commands
else if(expression) then
commands
else
commands
endif

case 的条件判断

项目 bash csh
case case expression in
pattern )
commands ;;
pattern )
commands ;;

esac
switch(“$value”)
case pattern1:
commands
breaksw
case pattern2:
commands
breaksw
default:
commands
breaksw
endsw
  • bash 的case的匹配模式可以使用各种通配符,下面是一些例子。

    • a):匹配a
    • a|b):匹配ab
    • [[:alpha:]]):匹配单个字母。
    • ???):匹配3个字符的单词。
    • *.txt):匹配.txt结尾。
    • *):匹配任意输入,通过作为case结构的最后一个模式。
  • Bash 4.0之前,case结构只能匹配一个条件,然后就会退出case结构。Bash 4.0之后,允许匹配多个条件,这时可以用 ;;& 终止每个条件块。

参考文献

  1. 脚本之家网.csh的基本语法介绍[EB/OL].https://www.jb51.net/article/57770.htm, 2020/12/21.

  2. iTech.csh 语法实例参考[EB/OL].https://www.cnblogs.com/itech/archive/2012/08/15/2640811.html, 2020/12/21.

  3. 阮一峰.Bash 脚本教程[EB/OL].https://wangdoc.com/bash, 2020/12/21.

    该教程的部分内容是比较完善的。

  4. 脚本之家.shell中各种括号的作用详解()、(())、[]、[[]]、{}[EB/OL].https://www.jb51.net/article/123081.htm, 2020/12/24.

姊妹篇

  1. csh 、 bash 的基础语法对照:变量

  2. csh 、 bash 的基础语法对照:判断表达式

  3. csh 、 bash 的基础语法对照:循环表达式