Shell 逻辑运算符涉及以下几种类型,只要适当选择,可以解决我们很多复杂的判断,达到事半功倍效果。
一、逻辑判断
1、关于文件与目录的逻辑判断
-f 常用。判断『文件』是否为普通文件,比如: if [ -f filename ]
-d 常用。判断『目录』是否存在
-b 判断是否为一个『 block 文件』
-c 判断是否为一个『 character 文件』
-S 判断是否为一个『 socket 标签文件』
-L 判断是否为一个『 symbolic link 的文件』
-e 判断『文件』是否存在
2、关于程序的逻辑判断
-G 判断是否由 GID 所执行的程序所拥有
-O 判断是否由 UID 所执行的程序所拥有
-p 判断是否为程序间传送信息的 name pipe 或是 FIFO
3、关于文件的属性判断
-r 判断是否为可读的属性
-w 判断是否为可以写入的属性
-x 判断是否为可执行的属性
-s 判断是否为『非空白文件』
-u 判断是否具有『 SUID 』的属性
-g 判断是否具有『 SGID 』的属性
-k 判断是否具有『 sticky bit 』的属性
4、两个文件之间的判断与比较
-nt 第一个文件比第二个文件新
-ot 第一个文件比第二个文件旧
-ef 第一个文件与第二个文件为同一个文件( link 之类的文件)
5. 布尔运算符
&& 逻辑与
|| 逻辑或
! 逻辑非
二、运算符号
= 等于 应用于:整型或字符串比较 如果在[] 中,只能是字符串
!= 不等于 应用于:整型或字符串比较 如果在[] 中,只能是字符串
< 小于 应用于:整型比较 在[] 中,不能使用表示字符串
> 大于 应用于:整型比较 在[] 中,不能使用表示字符串
-eq 等于 应用于:整型比较
-ne 不等于 应用于:整型比较
-lt 小于 应用于:整型比较
-gt 大于 应用于:整型比较
-le 小于或等于 应用于:整型比较
-ge 大于或等于 应用于:整型比较
-a 双方都成立(and) 相当于 &&
-o 单方成立(or) 相当于 ||
-z 空字符串
-n 非空字符串
三、逻辑表达式
注意:所有字符与逻辑运算符直接用“空格”分开,不能连到一起。
1、test 命令
使用方法:test EXPRESSION
如:
[root@localhost ~]# test 1 = 1 && echo 'ok'
ok
[root@localhost ~]# test -d /etc/ && echo 'ok'
ok
[root@localhost ~]# test 1 -eq 1 && echo 'ok'
ok
[root@localhost ~]# if test 1 = 1 ; then echo 'ok'; fi
ok
2、精简表达式
[] 表达式
[root@localhost ~]# [ 1 -eq 1 ] && echo 'ok'
ok
[root@localhost ~]# [ 2 < 1 ] && echo 'ok'
-bash: 1: No such file or directory
[root@localhost ~]# [ 2 \< 1 ] && echo 'ok'
[root@localhost ~]# [ 2 -gt 1 -a 3 -lt 4 ] && echo 'ok'
ok
[root@localhost ~]# [ 2 -gt 1 && 3 -lt 4 ] && echo 'ok'
-bash: [: missing `]'
注意:在[] 表达式中,常见的>,<需要加转义字符,表示字符串大小比较,以acill码位置作为比较。不直接支持<>运算符,还有逻辑运算符 || 和 && 它需要用-a[and] –o[or]表示。
[[]] 表达式
[root@localhost ~]# [ 1 -eq 1 ] && echo 'ok'
ok
[root@localhost ~]# [[ 2 < 3 ]] && echo 'ok'
ok
[root@localhost ~]# [[ 2 < 3 && 4 < 5 ]] && echo 'ok'
ok
注意:[[]] 运算符只是[]运算符的扩充。能够支持<,>符号运算不需要转义符,它还是以字符串比较大小。里面支持逻辑运算符 || 和 &&
bash 的条件表达式中有三个几乎等效的符号和命令:test,[]和[[]]。通常,大家习惯用if [];then这样的形式。而[[]]的出现,根据ABS所说,是为了兼容><之类的运算符。
不考虑对低版本bash和对sh的兼容的情况下,用[[]]是兼容性强,而且性能比较快,在做条件运算时候,可以使用该运算符。
Bash版本为4.1.5,可以man bash得到更多的信息,在里面找到对”CONDITIONAL EXPRESSIONS”的描述。
对于文件/字符串/数字分别有不同的条件表达式。(由于Bash也是将数字当成字符串处理的,所以数字的比较也可以用字符串的条件表达式。)
注意:
1. 字符串的比较用=, !=之类的,数字的比较用eq, gt之类的;
2. 字符串的“等于“比较,为了与POSIX一致,在[]中请用”=”.(尽管”==”也可以可以用的);
3. 字符串的>, <比较运算符,一般放在[[ ]]之中,而不是test ("[]");
4. 字符串的>, <比较的结果,与本地的locale有关,是按照其字典序列进行比较的。
下面对Bash中的条件表达式做个知识点的记录,然后附上一个简单的Bash测试脚本。
运算符 描述 示例
文件比较运算符
-e filename 如果 filename 存在,则为真 [ -e /var/log/syslog ]
-d filename 如果 filename 为目录,则为真 [ -d /tmp/mydir ]
-f filename 如果 filename 为常规文件,则为真 [ -f /usr/bin/grep ]
-L filename 如果 filename 为符号链接,则为真 [ -L /usr/bin/grep ]
-r filename 如果 filename 可读,则为真 [ -r /var/log/syslog ]
-w filename 如果 filename 可写,则为真 [ -w /var/mytmp.txt ]
-x filename 如果 filename 可执行,则为真 [ -L /usr/bin/grep ]
filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2 如果 filename1 比 filename2 旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)
-z string 如果 string 长度为零,则为真 [ -z $myvar ]
-n string 如果 string 长度非零,则为真 [ -n $myvar ]
string1 = string2 如果 string1 与 string2 相同,则为真 [ $myvar = one two three ]
string1 != string2 如果 string1 与 string2 不同,则为真 [ $myvar != one two three ]
string1 < string2 如果string1在本地的字典序列中排在string2之前,则为真 [[ $myvar < "one" ]]
string1 > string2 如果string1在本地的字典序列中排在string2之后,则为真 [[ $myvar > "one" ]]
算术比较运算符
num1 -eq num2 等于 [ 3 -eq $mynum ]
num1 -ne num2 不等于 [ 3 -ne $mynum ]
num1 -lt num2 小于 [ 3 -lt $mynum ]
num1 -le num2 小于或等于 [ 3 -le $mynum ]
num1 -gt num2 大于 [ 3 -gt $mynum ]
num1 -ge num2 大于或等于 [ 3 -ge $mynum ]
逻辑运算符
expr1 -a expr2 与 [ 1 -eq 1 -a 1 -ne 2 ]
expr1 -o expr2 或 [ 1 -ne 1 -o 1 -ne 2 ]
! expr1 非 [ ! -f myfile ]
#!/bin/bash
num=22
var="Jay"
file="/root/just-for-fun.txt"
if [ ! -f $file ]; then
echo "----new------" | tee $file
echo "just for fun." | tee -a $file
echo "$(date)" | tee -a $file
else
echo "---append----" | tee -a $file
echo "$(date)" | tee -a $file
fi
if [ 22 -eq $num ]; then
echo "num is equal to 22."
else
echo "num is NOT equal to 22."
fi
if [ "i""Jay" = "i""$var" ]; then
echo "var is equal to 'Jay'."
else
echo "var is NOT equal to 'Jay'."
fi
if [[ "Jay" > "jay" ]]; then
echo "'Jay' sorts after 'jay' lexicographically."
else
echo "'Jay' does NOT sort after 'jay' lexicographically."
fi