本文基于 GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)

bash 条件判断 的类型与逻辑运算符

字符串比较

  1. ===, 相同为真;
  2. !=, 不相同为真;
  3. -z, 长度为0(空)为真;
  4. -n, 长度不为0(非空)为真;
  5. <, 按字典序小于为真;
  6. >, 按字典序大于为真;

整数比较

  1. -eq, equals, 相等为真;
  2. -ne, not equals, 不相等为真;
  3. -gt, greater than, 大于为真;
  4. -ge, greater equals, 大于等于为真;
  5. -lt, less than, 小于为真;
  6. -le, less equals, 小于等于为真;
  7. >, 大于;
  8. >=, 大于等于;
  9. <, 小于;
  10. <=, 小于等于;
  11. ==, 等于;
  12. !=, 不等于;

文件比较

  1. -e, exists, 文件存在为真
  2. -r, read, 用户可读为真
  3. -w, write, 用户可写为真
  4. -x, execute, 用户可执行为真
  5. -f, file, 文件为正规文件为真
  6. -d, directory, 文件为目录为真
  7. -L, link, 文件为链接文件为真
  8. -c, char, 文件为字符特殊文件为真
  9. -b, block, 文件为块特殊文件为真
  10. -s, 文件大小非0时为真
  11. -t, 当文件描述符(默认为1)指定的设备为终端时为真
  12. -nt, newer than, 更新时间更晚为真;
  13. -ot, older than, 更新时间更早为真;

逻辑比较

  1. -a, and, 逻辑与;
  2. -o, or, 逻辑或;
  3. !, 逻辑非;
  4. &&, 逻辑与( 支持短路 );
  5. ||, 逻辑或( 支持短路 );

 

bash 条件判断 的命令(关键字)与语法

test 与 [ ]

test[ 是 shell 的内置命令;
test[] 可以用于比较字符串, 整数, 文件, test expr[ expr ]有等价的效果;

字符串比较

test可以使用=, ==, !=比较, bash 4.1版本下也能使用-n, -z比较字符串( 旧版本可能不支持该方式 );
[]可以使用上述全部的比较符号;

1
2
if !test $str1 == $str2; then ... ; fi
if ! [ $str1 == $str2 ]; then ... ; fi

test[] 也可以使用 <> 作字符串比较; 但是有一点要注意, test[是 shell 的内置命令, 使用 <> 需要转义, 否则会被当成重定向;

整数比较

test[]均可以使用-eq, -gt, -ge, -lt, -le, -ne 作整数比较, 但不能使用 >, >=, <, <=,==,!= 等比较运算符;
使用<,>,==,!=虽然语法不会报错, 但是会被当成字符串以字典序比较, 不能确保结果的正确性;

1
2
if test $1 -le 0; then ... ; fi
if [ $1 -le 0 ]; then ... ; fi

文件比较

test[]均可以使用-e, -r, -w, -x等文件比较逻辑;

1
2
if test -e /usr/local/localtime; then ... ; fi
if [ -e /usr/local/localtime ]; then ... ; fi

逻辑比较

test[]只能使用-a, -o!运算符, 但-a-o 不支持逻辑短路;

1
2
if !test $str1 == $str2 -a -n $str3; then ... ; fi
if [ $str1 == $str2 -a -n $str3 ]; then ... ; fi

test的返回值

test可以独立于if使用, 其执行结果( 0为真, 1为假 )可以使用$?来接收;

1
test -z "$1"; echo "$?"

bash关键字 [[ ]] ( 推荐使用 )

[[ 是 bash 的关键字, 而不是命令;
[[ ]][] 更通用, 更安全, 功能更强大; 在生产环境中, 推荐使用 [[ ]];

字符串比较

[[ ]] 除了可以使用基本的 =, ==, !=, -n, -z 之外, 其 =,==!=还有通配符模式匹配的功能:

1
2
# 模式串不能加双引号, 否则会被当作普通串
if [[ "test" == t* ]]; then ... ; fi

[[ ]] 还可以使用支持正则表达式的 =~ 运算符:

1
2
# 模式串不能加双引号, 否则会被当作普通串
if [[ "test" =~ ^t[a-z].t$ ]]; then ... ; fi

[[ ]]也可以使用<>作字符串比较; 由于[[是bash内置的关键字, <>并不会被当成重定向, 所以可以不需要转义;

整数比较

test, []一样, [[ ]]可以使用-eq, -gt, -ge, -lt, -le, -ne 作整数比较, 但不能使用 >, >=, <, <=,==,!= 等比较运算符; 不能使用的原因也是一样的(当成字符串来处理了);

算术拓展

[[]]支持算术拓展, 但是其对整数比较支持度较差, 算术拓展可能是一个鸡肋功能, 而且运算符与运算数之间不能有空格:

1
if [[ 1+1 -eq 2 ]]; then ... ; fi

此功能不推荐使用;

文件比较

test, []一样, [[ ]]可以使用-e, -r, -w, -x等文件比较逻辑;

逻辑比较

[[ ]]只能使用&&, ||, !运算符, 且&&||支持逻辑短路;

(( ))的使用场景

无论是test, []还是[[ ]], 都不能很好地使用<>处理整数的比较运算;
所以通常使用(())来处理整数的比较运算;
(())可以使用>, >=, <, <=,==,!=运算符;

1
if (( 1 + 1 == 2 )); then ... ; fi

使用(())的时候, 如果使用到了变量, 可以不需要加上$符号;

 

总结

- test 与 [ ] [[ ]] (( ))
字符串比较 =, ==, !=, -n, -z, <, > =, ==, !=, -n, -z, <, > 不支持
整数比较 -eq, -gt, -ge, -lt, -le, -ne -eq, -gt, -ge, -lt, -le, -ne >, >=, <, <=, ==, !=
文件比较 -e, -r, -w, -x, -f, -d, -L, -s, -b, -c, -t, -nt, -ot -e, -r, -w, -x, -f, -d, -L, -s, -b, -c, -t, -nt, -ot 不支持
逻辑比较 -a, -o, ! &&, ||, ! &&, ||, !

 

参考链接