本文基于 GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
bash 条件判断 的类型与逻辑运算符
字符串比较
=同==, 相同为真;!=, 不相同为真;-z, 长度为0(空)为真;-n, 长度不为0(非空)为真;<, 按字典序小于为真;>, 按字典序大于为真;
整数比较
-eq, equals, 相等为真;-ne, not equals, 不相等为真;-gt, greater than, 大于为真;-ge, greater equals, 大于等于为真;-lt, less than, 小于为真;-le, less equals, 小于等于为真;>, 大于;>=, 大于等于;<, 小于;<=, 小于等于;==, 等于;!=, 不等于;
文件比较
-e, exists, 文件存在为真-r, read, 用户可读为真-w, write, 用户可写为真-x, execute, 用户可执行为真-f, file, 文件为正规文件为真-d, directory, 文件为目录为真-L, link, 文件为链接文件为真-c, char, 文件为字符特殊文件为真-b, block, 文件为块特殊文件为真-s, 文件大小非0时为真-t, 当文件描述符(默认为1)指定的设备为终端时为真-nt, newer than, 更新时间更晚为真;-ot, older than, 更新时间更早为真;
逻辑比较
-a, and, 逻辑与;-o, or, 逻辑或;!, 逻辑非;&&, 逻辑与( 支持短路 );||, 逻辑或( 支持短路 );
bash 条件判断 的命令(关键字)与语法
test 与 [ ]
test 与 [ 是 shell 的内置命令;test 和 [] 可以用于比较字符串, 整数, 文件, test expr 与[ expr ]有等价的效果;
字符串比较
test可以使用=, ==, !=比较, bash 4.1版本下也能使用-n, -z比较字符串( 旧版本可能不支持该方式 );[]可以使用上述全部的比较符号;
1 | if !test $str1 == $str2; then ... ; fi |
test 与 [] 也可以使用 < 和 > 作字符串比较; 但是有一点要注意, test和[是 shell 的内置命令, 使用 < 和 > 需要转义, 否则会被当成重定向;
整数比较
test和[]均可以使用-eq, -gt, -ge, -lt, -le, -ne 作整数比较, 但不能使用 >, >=, <, <=,==,!= 等比较运算符;
使用<,>,==,!=虽然语法不会报错, 但是会被当成字符串以字典序比较, 不能确保结果的正确性;
1 | if test $1 -le 0; then ... ; fi |
文件比较
test和[]均可以使用-e, -r, -w, -x等文件比较逻辑;
1 | if test -e /usr/local/localtime; then ... ; fi |
逻辑比较
test和[]只能使用-a, -o和!运算符, 但-a和-o 不支持逻辑短路;
1 | if !test $str1 == $str2 -a -n $str3; then ... ; fi |
test的返回值
test可以独立于if使用, 其执行结果( 0为真, 1为假 )可以使用$?来接收;
1 | test -z "$1"; echo "$?" |
bash关键字 [[ ]] ( 推荐使用 )
[[ 是 bash 的关键字, 而不是命令;[[ ]] 比 [] 更通用, 更安全, 功能更强大; 在生产环境中, 推荐使用 [[ ]];
字符串比较
[[ ]] 除了可以使用基本的 =, ==, !=, -n, -z 之外, 其 =,== 和 !=还有通配符模式匹配的功能:
1 | # 模式串不能加双引号, 否则会被当作普通串 |
[[ ]] 还可以使用支持正则表达式的 =~ 运算符:
1 | # 模式串不能加双引号, 否则会被当作普通串 |
[[ ]]也可以使用<和>作字符串比较; 由于[[是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, ! | &&, ||, ! | &&, ||, ! |