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