zl程序教程

您现在的位置是:首页 >  后端

当前栏目

04·Shell编程-条件表达式

编程shell 条件 表达式 04
2023-06-13 09:11:05 时间

-曾老湿, 江湖人称曾老大。


-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。


条件表达式

条件表达式介绍

条件表达式,我们非常的常用,可以说,任何编程语言,都离不开条件表达式,但是每种变成语言的写法都不太一样,在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.判断目录是否存在
[root@zabbix01 ~]# test -d /etc && echo '存在' || '不存在'
存在
[root@zabbix01 ~]# [ -d /etc ] && echo '存在' || '不存在'
存在
[root@zabbix01 ~]# [[ -d /etc ]] && echo '存在' || '不存在'
存在


# 2.判断文件是否存在
[root@zabbix01 ~]# [[ -f /etc/hosts ]] && echo '存在' || echo '不存在'
存在
[root@zabbix01 ~]# [ -f /etc/hosts ] && echo '存在' || echo '不存在'
存在
[root@zabbix01 ~]# test -f /etc/hosts && echo '存在' || echo '不存在'
存在


# 3.判断是否存在,不区分目录或文件
[root@zabbix01 ~]# test -e /etc/hosts && echo '存在' || echo '不存在'
存在
[root@zabbix01 ~]# [ -e /etc/hosts ] && echo '存在' || echo '不存在'
存在
[root@zabbix01 ~]# [[ -e /etc/hosts ]] && echo '存在' || echo '不存在'
存在

# 4.判断权限,注意如果是root用户,只能判断出来执行权限,使用普通用户即可
[root@zabbix01 ~]# ll /etc/shadow
---------- 1 root root 791 Aug 17 19:57 /etc/shadow
[root@zabbix01 ~]# [ -x /etc/shadow ] && echo '存在' || echo '不存在'
不存在
[root@zabbix01 ~]# [ -r /etc/shadow ] && echo '存在' || echo '不存在'
存在
[root@zabbix01 ~]# [ -w /etc/shadow ] && echo '存在' || echo '不存在'
存在

# 5.判断文件是否为空
[root@zabbix01 ~]# echo 123 >1.txt
[root@zabbix01 ~]# touch 2.txt
[root@zabbix01 ~]# [ -s 1.txt ] && echo '不为空' || echo '空文件'
不为空
[root@zabbix01 ~]# [ -s 2.txt ] && echo '不为空' || echo '空文件'
空文件

# 6.判断文件是否是软链接文件
[root@zabbix01 ~]# [ -L /bin ] && echo '软链接' || echo '非软链接'
软链接

# 7.判断文件新或旧 (修改时间)
[root@zabbix01 ~]# [ 1.txt -nt 2.txt ] && echo '1.txt比2.txt更新' || echo '2.txt比1.txt更新'
2.txt比1.txt更新
[root@zabbix01 ~]# [ 1.txt -ot 2.txt ] && echo '1.txt比2.txt更旧' || echo '2.txt比1.txt更旧'
1.txt比2.txt更旧

## 条件表达式使用格式
[ 条件 ] && cmd


[ 条件 ] && {
cmd1
cmd2
}

优化计算器

没错,还是它。

需求:给脚本传递两个参数,然后求出他们的:和、差、积、商

编写思路: 用户是顽皮的,所以我们一定要写好判断。 1.首先要判断传递的是不是两个参数 2.然后判断两个参数是不是都是数字 确认之后,才能计算结果

[root@zabbix01 script]# vim cal.sh
#!/bin/bash


[ $# -ne 2 ] && {
  echo '请输入两个参数 OJBK?'
  exit 1
}

expr $1 + $2 + 666 &>/dev/null
[ $? -ne 0 ] && {
  echo '这是计算器,你不输入数字,算nm呢?'
  exit 2
}

awk -v n1=$1 -v n2=$2 'BEGIN{print n1+n2}'
awk -v n1=$1 -v n2=$2 'BEGIN{print n1-n2}'
awk -v n1=$1 -v n2=$2 'BEGIN{print n1*n2}'
awk -v n1=$1 -v n2=$2 'BEGIN{print n1/n2}'


[root@zabbix01 script]# sh cal.sh
请输入两个参数 OJBK?
[root@zabbix01 script]# echo $?
1
[root@zabbix01 script]# sh cal.sh 10 a
这是计算器,你不输入数字,算nm呢?
[root@zabbix01 script]# echo $?
2
[root@zabbix01 script]# sh cal.sh 10 20
30
-10
200
0.5

字符串表达式

字符串表达式介绍

注意:大写的注意,在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这样的方式,如果使用这样的方式,那莫不如就用[]

[root@zabbix01 script]# [[ 18 >= 16 ]] && echo 1 || echo 2
-bash: syntax error in conditional expression
-bash: syntax error near `16'
[root@zabbix01 script]# [[ 18 \>= 16 ]] && echo 1 || echo 2
-bash: conditional binary operator expected
-bash: syntax error near `\>='
[root@zabbix01 script]# [[ 18\>= 16 ]] && echo 1 || echo 2
-bash: conditional binary operator expected
-bash: syntax error near `16'
[root@zabbix01 script]# [[ 18\>=16 ]] && echo 1 || echo 2
1

[root@zabbix01 script]# [[ 18 -ge 16 ]] && echo 1 || echo 2
1
[root@zabbix01 script]# [ 18 -ge 16 ] && echo 1 || echo 2
1

## 不要在[]中使用>和<,能不能使用呢?也能但是又坑
[root@zabbix01 script]# age=30
[root@zabbix01 script]# [ $age > 20 ] && echo '真' || echo '假'
真
[root@zabbix01 script]# [ $age > 50 ] && echo '真' || echo '假'
真

## 这里把>当成了重定向
[root@zabbix01 script]# 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

## 那么应该怎么用?转义符
[root@zabbix01 script]# age=30
[root@zabbix01 script]# [ $age \> 50 ] && echo '真' || echo '假'
假
[root@zabbix01 script]# [ $age \> 10 ] && echo '真' || echo '假'
真

## 还是有坑,为啥呢。再举个例子
[root@zabbix01 script]# age=2
[root@zabbix01 script]# echo $age
2
[root@zabbix01 script]# [ $age \> 19 ] && echo '真' || echo '假'
真

## 为啥还是真呢?因为这个时候做大小比较的时候,按照字符串根据ASCII中的排序
[root@zabbix01 script]# seq 20|sort
1
10
11
12
13
14
15
16
17
18
19
2
20
3
4
5
6
7
8
9

所以,两个中括号是不是一无是处呢?之前我们说,他们可以使用正则。

[[]]的成员运算

举几个例子就明白了。

# 1.判断变量中是否包含18
[root@zabbix01 script]# [[ $name =~ 18 ]] && echo '有18' || echo '木有18'
有18

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

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

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

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

## 然鹅,我们并不知道用户会传递多少位的数字啊。
## 于是我们需要使用正则表达式中的,+ 如果放在数字后面,代表连续的数字
[root@zabbix01 script]# [[ $name =~ ^[0-9]+$ ]] && echo '只有数字' || echo '木有数字'
只有数字

逻辑运算表达式

逻辑运算表达式介绍

表达式

含义

符号

!

非,取反

!

&&

-a

||

-o

and条件

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

逻辑符号

条件1

条件2

结果

-a

or条件

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

逻辑符号

条件1

条件2

结果

-o

Shell 练习

企业面试题1

命令行中输入一个数字,如果数字是1,则输出1,如果是2则输出2,既不是1也不是2则显示脚本使用方法,并退出程序

[root@zabbix01 script]# 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


[root@zabbix01 script]# sh expression.sh 1
1
[root@zabbix01 script]# sh expression.sh 2
2
[root@zabbix01 script]# sh expression.sh 3
Usage: expression.sh Please Input 1 or 2

## 有瑕疵,如果用户输入的是字符串...
[root@zabbix01 script]# 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

企业面试题2

使用read进行传参,实现两个整数比较大小,并将结果打印到屏幕。

自己写,写不出来问我。