本文基于 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
2if !test $str1 == $str2; then ... ; fi
if ! [ $str1 == $str2 ]; then ... ; fi
test
与 []
也可以使用 <
和 >
作字符串比较; 但是有一点要注意, test
和[
是 shell 的内置命令, 使用 <
和 >
需要转义, 否则会被当成重定向;
整数比较
test
和[]
均可以使用-eq
, -gt
, -ge
, -lt
, -le
, -ne
作整数比较, 但不能使用 >
, >=
, <
, <=
,==
,!=
等比较运算符;
使用<
,>
,==
,!=
虽然语法不会报错, 但是会被当成字符串以字典序比较, 不能确保结果的正确性;1
2if test $1 -le 0; then ... ; fi
if [ $1 -le 0 ]; then ... ; fi
文件比较
test
和[]
均可以使用-e
, -r
, -w
, -x
等文件比较逻辑;1
2if test -e /usr/local/localtime; then ... ; fi
if [ -e /usr/local/localtime ]; then ... ; fi
逻辑比较
test
和[]
只能使用-a
, -o
和!
运算符, 但-a
和-o
不支持逻辑短路;1
2if !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, ! | &&, ||, ! | &&, ||, ! |