[toc]

条件表达式

条件表达式介绍

条件表达式,我们非常的常用,可以说,任何编程语言,都离不开条件表达式,但是每种变成语言的写法都不太一样,在shell中,有一种独特的写法。

条件测试语句

条件测试语句,我们又叫做test语句。

格式 介绍
test <条件> 常规判断命令
[[ <条件> ]] 支持运算符和正则的条件表达式
[ <条件> ] 常用条件表达式

文件表达式

表达式 含义 举例
-d 判断目录是否存在 test -d /etc
-f 判断文件是否存在 test -f /etc/hosts
-e 判断是否存在 test -e /etc
-r 判断文件是否存在,并且有read权限 test -r /etc/hosts
-w 判断文件是否存在,并且有write权限 test -w /etc
-x 判断文件是否存在,并且有execute权限 test -x /bin/ls
-s 判断文件是否存在,并且size是否大于0 test -s /etc/passwd
-L 判断文件是否存在,并且是否是软链接文件 test -L /bin
file1 -nt file2 file1是否比file2更新,newer than test 1.txt -nt 2.txt
file1 -ot file2 file1是否比file2更旧,older than test 1.txt -ot 2.txt

使用详解

  1. “-d”判断目录是否存在

    1
    2
    3
    4
    5
    6
    test -d /etc && echo '存在' || '不存在'
    存在
    [ -d /etc ] && echo '存在' || '不存在'
    存在
    [[ -d /etc ]] && echo '存在' || '不存在'
    存在
  2. “-f”判断文件是否存在

    1
    2
    3
    4
    5
    6
    [[ -f /etc/hosts ]] && echo '存在' || echo '不存在'
    存在
    [ -f /etc/hosts ] && echo '存在' || echo '不存在'
    存在
    test -f /etc/hosts && echo '存在' || echo '不存在'
    存在
  3. “-e”判断是否存在,不区分目录或文件

    1
    2
    3
    4
    5
    6
    test -e /etc/hosts && echo '存在' || echo '不存在'
    存在
    [ -e /etc/hosts ] && echo '存在' || echo '不存在'
    存在
    [[ -e /etc/hosts ]] && echo '存在' || echo '不存在'
    存在
  4. “-r/-w/-x”判断权限,注意如果是root用户,只能判断出来执行权限,使用普通用户即可

    1
    2
    3
    4
    5
    6
    7
    8
     ll /etc/shadow
    ---------- 1 root root 791 Aug 17 19:57 /etc/shadow
    [ -x /etc/shadow ] && echo '存在' || echo '不存在'
    不存在
    [ -r /etc/shadow ] && echo '存在' || echo '不存在'
    存在
    [ -w /etc/shadow ] && echo '存在' || echo '不存在'
    存在
  5. “-s”判断文件是否为空

    1
    2
    3
    4
    5
    6
    echo 123 >1.txt
    touch 2.txt
    [ -s 1.txt ] && echo '不为空' || echo '空文件'
    不为空
    [ -s 2.txt ] && echo '不为空' || echo '空文件'
    空文件
  6. “-L”判断文件是否是软链接文件

    1
    2
    [ -L /bin ] && echo '软链接' || echo '非软链接'
    软链接
  7. “-nt”判断文件哪个较新(修改时间)

    1
    2
    [ 1.txt -nt 2.txt ] && echo '1.txt比2.txt更新' || echo '2.txt比1.txt更新'
    2.txt比1.txt更新
  8. “-ot”判断文件哪个较旧(修改时间)

    1
    2
    [ 1.txt -ot 2.txt ] && echo '1.txt比2.txt更旧' || echo '2.txt比1.txt更旧'
    1.txt比2.txt更旧
  9. 条件表达式在脚本使用格式

    1
    2
    3
    4
    5
    6
    7
    8
    # 示例一(单个命令)
    [ 条件 ] && 命令

    # 示例二(多个命令)
    [ 条件 ] && {
    命令1
    命令2
    }

字符串表达式

字符串表达式介绍

注意:在shell脚本中所有变量的调用,请一定加上双引号,尤其是和字符串相关的,都要加双引号。

字符串表达式

表达式 含义 举例
-n not null 非空则成立 test -n ‘zls’
-z null 空则成立 test -z ‘zls’
“str1” = “str2” 等号左边字符串与右边字符串相等则成立 test ‘zls’ = ‘cls’
“str1” != “str2” 等号左边字符串与右边字符串不等则成立 test ‘zls’ != ‘cls’

整数表达式

整数表达式介绍

表达式 含义 test举例 [[]]举例
-eq equal 等于 test 2 -eq 2 [[ 2 -eq 2 ]]
-ne not equal 不等于 test 2 -ne 2 [[ 2 != 2 ]]
-gt great than 大于 test 2 -gt 2 [[ 2 > 2 ]]
-ge great equal 大于等于 test 2 -ge 2 [[ 2 >= 2 ]]
-lt less than 小于 test 2 -lt 2 [[ 2 < 2 ]]
-le less equal 小于等于 test 2 -le 2 [[ 2 <= 2 ]]

注意:当[[ ]] 遇到大于,基本就歇菜了,需要使用转译符,那么系统就推荐使用-ge,-gt这样的方式,如果使用这样的方式,那莫不如就用[ ]

符号表达使用解析:一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 符号使用说明
## 示例一
[[ 18 >= 16 ]] && echo 1 || echo 2
-bash: syntax error in conditional expression
-bash: syntax error near `16'
## 示例二
[[ 18 \>= 16 ]] && echo 1 || echo 2
-bash: conditional binary operator expected
-bash: syntax error near `\>='
## 示例三
[[ 18\>= 16 ]] && echo 1 || echo 2
-bash: conditional binary operator expected
-bash: syntax error near `16'
## 正确示例
[[ 18\>=16 ]] && echo 1 || echo 2
1
## 注意
1.需要使用转译符"\"
2.不能有空格

# 整数表达式使用解析
## 示例一
[[ 18 -ge 16 ]] && echo 1 || echo 2
1
## 示例二
[ 18 -ge 16 ] && echo 1 || echo 2
1

符号表达使用解析:二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 在[]中直接使用">"或"<"
## ">"或"<"会被识别成从定向符号
age=30
[ $age > 20 ] && echo '真' || echo '假'

[ $age > 50 ] && echo '真' || echo '假'

## 这里把>当成了重定向
ll
-rw-r--r-- 1 root root 0 Aug 31 17:04 20
-rw-r--r-- 1 root root 0 Aug 31 17:04 50

# 正确示例
## 那么应该怎么用"?"转译符
ge=30
[ $age \> 50 ] && echo '真' || echo '假'

[ $age \> 10 ] && echo '真' || echo '假'


# 排序错误示例
## 还是有坑,为啥呢。再举个例子
age=2
echo $age
2
[ $age \> 19 ] && echo '真' || echo '假'

## 为啥还是真呢?因为这个时候做大小比较的时候,按照字符串根据ASCII中的排序
seq 20|sort
18
19
2
20
3
...

[[]]的成员运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 1.判断变量中是否包含18
[[ $name =~ 18 ]] && echo '有18' || echo '木有18'
有18

# 2.判断变量中是否有数字
[[ $name =~ [0-9] ]] && echo '有数字' || echo '木有数字'
有数字

# 3.判断变量是否只有数字
## 方法一:
expr
## 方法二:
name=6
[[ $name =~ ^[0-9]$ ]] && echo '只有数字' || echo '木有数字'
只有数字

## 但是如果这样,只能匹配一个数字
name=66
[[ $name =~ ^[0-9]$ ]] && echo '只有数字' || echo '木有数字'
木有数字

## 那么我们就得再加一个
[[ $name =~ ^[0-9][0-9]$ ]] && echo '只有数字' || echo '木有数字'
只有数字

## 如需传递多位数字,我们可以使用正则表达式中的,+ 如果放在数字后面,代表连续的数字,匹配多个
[[ $name =~ ^[0-9]+$ ]] && echo '只有数字' || echo '木有数字'
只有数字

逻辑运算表达式

逻辑运算表达式介绍

表达式 含义 符号
! 非,取反 !
&& -a
|| -o

and条件

只有都为真,条件才为真,条件中有任何一个为假,那么结果就是假

逻辑符号 条件1 条件2 结果
-a
-a
-a
-a

or条件

只要有一个为真,结果就是真,除非两个都为假,结果才是假。

逻辑符号 条件1 条件2 结果
-o
-o
-o
-o

Shell 练习

企业面试题1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 需求:
命令行中输入一个数字,如果数字是1,则输出1,如果是2则输出2,既不是1也不是2则显示脚本使用方法,并退出程序

# 错误示例一
## vim expression.sh
#!/bin/bash
num=$1
[ $num -ne 1 -a $num -ne 2 ] && {
echo "Usage: $0 Please Input 1 or 2"
exit 1
}
[ $num -eq 1 ] && echo $num

[ $num -eq 2 ] && echo $num

## sh expression.sh 1
1
## sh expression.sh 2
2
## sh expression.sh 3
Usage: expression.sh Please Input 1 or 2
## 解析
有瑕疵,如果用户输入的是字符串...

# 错误示例二
## vim expression.sh
#!/bin/bash
num=$1
[[ $num =~ ^[0-9]$ ]] || echo 'Please Input A Int.'
[ $num -ne 1 -a $num -ne 2 ] && {
echo "Usage: $0 Please Input 1 or 2"
exit 1
}
[ $num -eq 1 ] && echo $num
[ $num -eq 2 ] && echo $num

## 解析
还是有瑕疵,会报错...下面的条件继续匹配了
#!/bin/bash
num=$1
[[ $num =~ ^[0-9]$ ]] || {
echo 'Please Input A Int.'
exit 2
}
[ $num -ne 1 -a $num -ne 2 ] && {
echo "Usage: $0 Please Input 1 or 2"
exit 1
}
[ $num -eq 1 ] && echo $num
[ $num -eq 2 ] && echo $num

# 正确示例一
num=$1
[ $num -eq 1 -o $num -eq 2 ] && echo $num || echo "Usage: $0 {1|2}"
[[ $num =~ ^[1-2]$ ]] && echo $num || echo "Usage: $0 {1|2}"

# 正确示例二
num=$1
if [ $num -eq 1 -o $num -eq 2 ];then
echo $num
else
echo "Usage: $0 {1|2}"
fi

拓展作业

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 需求
使用read进行传参,实现两个整数比较大小,并将结果打印到屏幕。

# 交付方案
#!/bin/bash
read -p '请输入第一位整数:' num1
if [[ $num1 =~ ^[0-9]+$ ]];then
expr $num1 + 0 &> /dev/null
else
echo '请输入整数OK???'
exit 1
fi

read -p '请输入第一位整数:' num2
if [[ $num2 =~ ^[0-9]+$ ]];then
expr $num2 + 0 &> /dev/null
else
echo '请输入整数lj???'
exit 1
fi

if [[ $num1 -gt $num2 ]];then
echo "$num1 > $num2"
elif [[ $num1 -lt $num2 ]];then
echo "$num1 < $num2"
else
echo "$num1 = $num2"
fi