05表达式

48 阅读10分钟

表达式

运算符

运算符基础

需求

根据我们之前的学习,通过现有的知识内容可以完成一个简单的功能操作,即使通过所谓的脚本参数可以实现一个脚本在多个数据值的情况下实现不同的结果。但是问题是,目前脚本本身还没有实现灵活的机制。所谓脚本级别的灵活机制,说的是脚本内部能够实现数据的操作和判断。而数据的操作也是判断过程中必须的一个条件组成部分。所以数据的操作是脚本的一个核心内容

数据操作

关于shell可以实施的数据操作,按照不同的业务场景主要可以分为如下两个方面:

  1. 运算符 - 数据值之间的操作
    • 赋值运算,结果值输出,示例: =、*=、/=、%=、+=、-=、<<=、>>=、&=、^=、|=等
    • 二元运算,数据值操作,示例: +、-、*、/、%等
    • 高阶运算,更高一级的数学运算,示例:**、^、++、--等
    • 其他运算,其他运算操作,示例:<<、>>等
  2. 表达式 - 数据值在特定场景的运算符操作
    • 计算表达式,将多个值的运算操作执行起来,示例:bc、let、expr、$(())等
    • 测试表达式,判断结果值是否满足需求,示例:test、[]等
    • 逻辑表达式,多条件的多场景组合,示例:&&、||、and、or、not、&、|等
    • 比较表达式,判断数据之间的适配关系,示例:-f|d|s、-r|x|w、-e、-n、==、!=、>、<、<=、>=等
    • 三元表达式,多逻辑的简单计算表达式,示例:expr?expr:expr
    • 集合表达式 ,表达式之间的关联关系,示例:expr1 , expr2、 [[ ]]、[ -a|o ]、[ ! ]等

注意:这些所谓的运算符一般很难单独来使用,都需要结合计算表达式来实现相应的效果

赋值运算

所谓的赋值运算,其实指的就是将一个值赋予一个变量名,虽然我们在变量一节中对于该知识点进行了一些基础性的操作,但是赋值运算仍然还有一些其他的表现样式,尤其是关于命令计算相关的

# 为变量赋值
num=123 string=abc

echo $num $string
123 abc

# 赋值时定制属性
declare stringnum=123
declare string=nihao

echo $stringnum $string
123 nihao

declare -i num=654
declare -i num2=aaa

echo $num $num2
654 0

# 获取特定数据
myuser=$(whoami)

echo $myuser
root

kernel_info=$(cat /etc/redhat-release)

echo $kernel_info
CentOS Linux release 7.9.2009 (Core)

简单计算

$[]

$[]方法,常用于整数计算场景,适合不太复杂的计算,运算结果是小数的也会自动取整,[]中可以存在空格,运算符前后也可以存在空格。后面的几种也是一样

  • 方法1,$[计算表达式]
  • 方法2,a=$[变量名a+1]

注意:这里的表达式可以不是一个整体

# 简单运算
echo $[100/5]
20

echo $[ 2 + 5 ]
7

# 变量参与运算
a=6
a=$[a+1]

echo $a
7

# 运算结果取整
echo $[100/3]
33

let

let是另外一种相对来说比较简单的数学运算符号了

格式:let 变量名a=变量名a+1,注意:表达式必须是一个整体,中间不能出现空格等特殊字符

# 简单运算
i=1
let i=i+7

echo $i
8

# let表达式必须是一个整体
let i = i * 2
-bash: let: =: syntax error: operand expected (error token is "=")

let i=i * 2
-bash: let: anaconda-ks.cfg: syntax error: invalid arithmetic operator (error token is ".cfg")

# 这个表达式才正确
let i=i*2

echo $i
16

(())

(())的操作与let基本一致,相当于let替换成了 (())

格式:((变量计算表达式))。注意:对于 $(())中间的表达式,可以不是一个整体,不受空格的限制

num1=34
((num2=num1+34))
(( num2 = num1 + 34 ))

echo $num2
68

$(())

(())的操作,相当于(())+echo(())的操作,相当于 (()) + echo 变量名 的组合(其实就是将计算结果返回)

格式:echo ((变量计算表达式)),对于((变量计算表达式)),对于 (())中间的表达式,可以不是一个整体,不受空格的限制

num1=34
# 返回的结果不能直接输出,仍然需要echo输出
$((num2=num1+34))
-bash: 68: command not found

echo $((num2=num1+34))
68

echo $(( num2 = num1 + 34 ))
68

赋值运算进阶

二元运算

所谓的二元运算,指的是多个数字进行+-*/%等运算

# 加法运算
echo $(( 4 + 4 ))
8

num1=3 num2=4

echo $(($num1+$num2))
7

# 减法运算
echo $((8-2))
6

echo $(($num2-$num1))
1

# 乘法运算
echo $((8*2))
16

echo $(($num2*$num1))
12

# 除法运算
echo $((8/2))
4

echo $(($num2/$num1))
1

# 取余运算
echo $((8%3))
2

echo $(($num2%$num1))
1

案例实践-小学计算题

案例需求:鸡兔同笼,共有30个头,88只脚。求笼中鸡兔各有多少只?

count_head_feet.sh,创建脚本文件,内容如下

#!/bin/bash
# 功能:小学计算题目
# 版本:v0.1
# 作者:example
# 联系:www.example.com

# 定制普通变量
head="$1"
feet="$2"

# 计算逻辑
# 每个头至少两只脚,多出的脚都是兔子的
rabbit_num=$(( ($feet - $head - $head) / 2))
chick_num=$[ $head - $rabbit_num ]

# 结果输出
echo -e "\e[31m\t鸡和兔的数量\e[0m"
echo -e "\e[32m============================"
echo "鸡的数量: ${chick_num}"
echo "兔的数量:${rabbit_num}"
echo -e "============================\e[0m"
/bin/bash count_head_feet.sh 30 88
        鸡和兔的数量
============================
鸡的数量: 16
兔的数量:14
============================

赋值运算

这里的赋值运算,是一种进阶版本的赋值操作,常见的样式如下:

  • 样式1:+=、-=、*=、/=,在自身的基础上进行二元运算,结果值还是自己
  • 样式2:++、--,在自身的基础上进行递增和递减操作,结果值还是自己
# +=运算
num1=6
# 相当于 let value=value+$num1
let value+=$num1

echo $value
6

# -=运算
# 相当于 let value=value-2
let value-=2

echo $value
4

# *=运算
# 相当于 let value=value*2
let value*=2

echo $value
8

# /=运算
# 相当于 let value=value/2
let value/=2

echo $value
4

# i++运算
value=9
# 相当于 let value=value+1
let value++

echo $value
10

let value++

echo $value
11

# ++i运算
# 相当于 let value=value+1
let ++value

echo $value
12

# --运算
value=9
# 相当于 let value=value-1
let value--

echo $value
8

let value--

echo $value
7

# 相当于 let value=value-1
let --value

echo $value
6

expr计算

expr即可以做常见的整数运算,还可以做数字比较,字符串计算等操作,因为*()这些操作符在shell中有特殊的含义,需要加转义符

格式

  1. 数字场景,expr 运算表达式,注意运算符两边需要加空格
  2. 字符串场景
    • expr match 字符串 匹配内容用户获取匹配到字符串的长度,必须从左边第一个字符匹配
    • expr substr 字符串 起始位置 截取长度截取字符串,注意:起始位置值>=1
    • expr index 字符串 字符查找第一次匹配字符的位置
    • expr length 字符串计算字符串的长度

简单实践

# 数学运算
expr 1 + 2 - 3 \* 4 / 5 + \( 6 - 7 \) \* 8
-7

x=1

expr $x + 4
5

# 这里运算符两边需要加空格
expr $x+4
1+4
# 字符串运算
# 用户获取匹配到字符串的长度
file=jdslkfajkldsjafklds
# 必须从左边第一个字符匹配
expr match $file "k.*j"
0

expr match $file ".*j"
13

# 截取字符串
# 起始位置值>=1
expr substr $file 0 4

expr substr $file 1 4
jdsl

# 查找第一次匹配字符的位置
expr index $file b
0

expr index $file j
1

# 计算字符串的长度
expr length $file
19

expr length $file
19

bc计算

bc是一种任意精度的计算语言,提供了语法结构,比如条件判断、循环等,功能是很强大的,还能进行进制转换

选项说明
-i, --interactive强制交互模式
-l, --mathlib使用bc的内置库,bc里有一些数学库,对三角计算等非常实用
-w, --warn对POSIX bc的扩展发出警告
-s, --standard完全处理POSIX bc语言
-q, --quiet进入bc交互模式时不再输出版本等多余的信息

特殊变量 ibase,obase 用于进制转换,ibase是输入的进制,obase是输出的进制,默认是十进制;scale 小数保留位数,默认保留0位

简单实践

# 实践1-交互示例
# 在shell命令行直接输入bc即进入bc语言的交互模式
bc -l -q
4/3
1.33333333333333333333
3+4
7
5 * 8
40
exit
0
^C
(interrupt) Exiting bc.

# 实践2 - 非交互示例
# 格式:echo "属性设置; 计算表达式" | bc
echo "scale=2; 9-8*2/5^2" | bc
8.36

echo "scale=2; sqrt(10)" | bc
3.16

echo '45.36-22.33' | bc
23.03

实践3 - 内存使用率统计

memory_info.sh,创建脚本文件,内容如下

#!/bin/bash
# 功能:定制内存信息的使用率
# 版本:v0.1
# 作者:example
# 联系:www.example.com

# 定制基础信息
temp_file='/tmp/free.txt'
hostname=$(hostname)

# 获取内存信息
free -m > /tmp/free.txt
# 获得内存总量
memory_totle=$(grep -i "mem" /tmp/free.txt | tr -s " " | cut -d " " -f2)
# 获得内存使用的量
memory_use=$(grep -i "mem" /tmp/free.txt | tr -s " " | cut -d " " -f3)
# 获得内存空闲的量
memory_free=$(grep -i "mem" /tmp/free.txt | tr -s " " | cut -d " " -f4)

# 定制使用比例
# 获取内存使用率
percentage_use=$(echo "scale=2; $memory_use * 100 / $memory_totle" | bc)
# 定制内存空闲率
percentage_free=$(echo "scale=2; $memory_free * 100 / $memory_totle" | bc)

# 内容信息输出
echo -e "\e[31m\t${hostname} 内存使用信息统计\e[0m"
echo -e "\e[32m=========================================="
echo '内存总量:     ' ${memory_totle}
echo '内存使用量:   ' ${memory_use}
echo '内存空闲量:   ' ${memory_free}
echo '内存使用比率: ' ${percentage_use}
echo '内存空闲利率: ' ${percentage_free}
echo "=========================================="
echo -e "\e[0m"
/bin/bash memory_info.sh
        test 内存使用信息统计
==========================================
内存总量:      972
内存使用量:    258
内存空闲量:    125
内存使用比率:  26.54
内存空闲利率:  12.86
==========================================

表达式

基础知识

所谓的表达式,就是在场景需求的前提下,判断数据和运算符的操作是否满足需求

语法格式:真实值 操作符 真实值 比较运算符 预期值;示例:3 + 4 > 6;要点:表达式应该具有判断的功能

测试表达式

Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0,表示成功,值为其他时,表示失败。使用专门的测试工具test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值0为成立)

  • 样式1,test 条件表达式
  • 样式2,[ 条件表达式 ]

以上两种方法的作用完全一样,后者为常用。但后者需要注意方括号[、]与条件表达式之间至少有一个空格。test跟 [] 的意思一样,条件成立,状态返回值是0;条件不成立,状态返回值是1

# test语法示例
# 默认都是作为字符串比较的,可以只使用一个等于号
test 1 == 1

echo $?
0

test 1 == 2

echo $?
1

# test -v 语法测试变量有没有被设置值,亦可理解为变量是否为空
echo $empty
test -v empty

echo $?
1

empty=value
test -v empty

echo $?
0

# [] 语法示例
[ 1 == 1 ]

echo $?
0

[ 1 == 12 ]

echo $?
1

# 语法错误
[ 1 == 12]
-bash: [: missing `]'

# 语法正确
[ 1 == 12] ]

逻辑表达式

逻辑表达式一般用于判断多个条件之间的依赖关系。常见的逻辑表达式有:&& 和 ||,根据观察的角度不同含义也不同

语法解读

  • &&, 示例:命令1 && 命令2,如果命令1执行成功,那么我才执行命令2;如果命令1执行失败,那么命令2也不执行
  • ||, 示例:命令1 || 命令2,如果命令1执行成功,那么命令2不执行;如果命令1执行失败,那么命令2执行
  • !, 示例:! 命令,如果命令执行成功,则整体取反状态,该符号与命令之间的空格不能省略

组合使用

使用样式:命令1 && 命令2 || 命令3,方便理解的样式 (命令1 && 命令2) || 命令3。命令1执行成功的情况下,执行命令2;命令2执行失败的情况下,执行命令3。注意:组合使用时,逻辑符号的顺序很重要,顺序不一样表示的逻辑可能也不一样

简单实践

# 实践1-语法实践

# && 语法实践
[ 1 = 1 ] && echo "条件成立"
条件成立

[ 1 = 2 ] && echo "条件成立"

# || 语法实践
[ 1 = 2 ] || echo "条件不成立"
条件不成立

[ 1 = 1 ] || echo "条件不成立"

实践2-案例实践

test_argnum.sh,创建脚本文件,内容如下

#!/bin/bash
# && 和 || 演示

# 设定普通变量
arg_num=$#

[ $# == 1 ] && echo "脚本参数为1,允许执行脚本"
[ $# == 1 ] || echo "脚本参数不为1,不允许执行脚本"
/bin/bash test_argnum.sh
脚本参数不为1,不允许执行脚本

/bin/bash test_argnum.sh 1
脚本参数为1,允许执行脚本

/bin/bash test_argnum.sh 1 2
脚本参数不为1,不允许执行脚本

# 实践3-取反

# 查看正常的字符串判断
[ aaa == aaa ]

echo $?
0

# 查看取反的效果判断
[ ! aaa == aaa ]

echo $?
1

[ aaa != aaa ]

echo $?
1

[ ! aaa == bbb ]

echo $?
0

# 实践4 - 组合使用
# -d 是目录其存在
[ -d /etc ] && echo "目录存在" || echo "目录不存在"
目录存在

[ -d /etc1 ] && echo "目录存在" || echo "目录不存在"
目录不存在

实践5 - 主机网络连通性测试

host_network_test.sh,创建脚本文件,内容如下

#!/bin/bash
# 功能:测试主机网络连通性
# 版本:v0.1
# 作者:example
# 联系:www.example.com

# 定制普通变量
host_addr="$1"

# 脚本基本判断
# -z 后面字符串的长度为0
[ -z ${host_addr} ] && echo "请输入待测试主机ip" && exit
# -ne 左边不等于右边
[ $# -ne 1 ] && echo "请保证输入1个脚本参数" && exit

# 测试主机网络
net_status=$(ping -c1 -w1 ${host_addr} >/dev/null 2>&1 && echo "正常" || echo "异常")

# 信息输出
echo -e "\e[31m\t主机网络状态信息\e[0m"
echo -e "\e[32m================================"
echo "${host_addr} 网络状态: ${net_status}"
echo -e "================================\e[0m"
/bin/bash host_network_test.sh
请输入待测试主机ip

/bin/bash host_network_test.sh aa bb
请保证输入1个脚本参数

/bin/bash host_network_test.sh 192.168.91.100
        主机网络状态信息
================================
192.168.91.100 网络状态: 异常
================================

/bin/bash host_network_test.sh 192.168.91.101
        主机网络状态信息
================================
192.168.91.101 网络状态: 正常
================================

字符串表达式

所谓的字符串表达式,主要是判断 比较运算符 两侧的值的内容是否一致,由于bash属于弱类型语言,所以,默认情况下,无论数字和字符,都会可以被当成字符串进行判断

  1. 内容比较判断
    • str1 == str2str1和str2字符串内容一致
    • str1 != str2str1和str2字符串内容不一致,!表示相反的意思
  2. 内容空值判断
    • -z str空值判断,获取字符串长度,长度为0,返回True
    • -n "str"非空值判断,获取字符串长度,长度不为0,返回True。注意:str外侧必须携带"",否则无法判断(str为空时,不带双引号会判断错误)
# 实践1-内容比较判断

# 判断字符串内容是否一致
test aaa == bbb
echo $?
1

test aaa != bbb
echo $?
0

# 判断数字内容是否一致
num1=234 num2=456
test $num1 == $num2
echo $?
1

test $num1 != $num2
echo $?
0

# 实践2-空值判断

# 判断内容是否为空
string=nihao
test -z $string
echo $?
1

test -z $string1
echo $?
0

# 判断内容是否为不空,可以理解为变量是否被设置
unset str
[ -n $str ]
echo $?
0

[ -n "$str" ]
echo $?
1

str=value
[ -n "$str" ]
echo $?
0

实践3-脚本实践

simple_login_string.sh,创建脚本文件,内容如下

#!/bin/bash
# 功能: 模拟shell登录
# 版本:v0.1
# 作者:example
# 联系:www.example.com

# 定制命令变量
OS_INFO=$(cat /etc/redhat-release)
KERNEL_INFO=$(uname -r)
OS_ARCH=$(uname -m)
HOSTNAME=$(hostname)

# 清屏
clear

# 输出提示信息
echo -e "\e[32m${OS_INFO} \e[0m"
echo -e "\e[32mKernel ${KERNEL_INFO} on an ${OS_ARCH} \e[0m"
echo "---------------------------------"
# 交互输入登陆信息
read -p "请输入用户名:" account
[ -z $account ] && read -p "请输入用户名:" account
read -s -t30 -p "请输入登录密码:" password
echo
echo "---------------------------------"
# 输出用户输入信息
[ $account == 'root' ] && [ $password == '123456' ] && echo "登录成功" || echo "登录失败"
/bin/bash simple_login_string.sh
CentOS Linux release 7.9.2009 (Core)
Kernel 3.10.0-1160.71.1.el7.x86_64 on an x86_64
---------------------------------
请输入用户名:root
请输入登录密码:
---------------------------------
登录成功

/bin/bash simple_login_string.sh
CentOS Linux release 7.9.2009 (Core)
Kernel 3.10.0-1160.71.1.el7.x86_64 on an x86_64
---------------------------------
请输入用户名:root1
请输入登录密码:
---------------------------------
登录失败

文件表达式

所谓的文件表达式,主要是判断文件相关的权限和属性信息的

表达式解读

  1. 文件属性判断
    • -d 检查文件是否存在且为目录文件
    • -f 检查文件是否存在且为普通文件
    • -S 检查文件是否存在且为socket文件
    • -L 检查文件是否存在且为链接文件
    • -O 检查文件是否存在并且被当前用户拥有
    • -G 检查文件是否存在并且默认组为当前用户组
  2. 文件权限判断
    • -r 检查文件是否存在且可读
    • -w 检查文件是否存在且可写
    • -x 检查文件是否存在且可执行
  3. 文件存在判断
    • -e 检查文件是否存在
    • -s 检查文件是否存在且不为空
  4. 文件新旧判断
    • file1 -nt file2 检查file1是否比file2新
    • file1 -ot file2 检查file1是否比file2旧
    • file1 -ef file2 检查file1是否与file2是同一个文件,判定依据是具有相同的设备和索引节点编号

简单实践

# 实践1- 文件属性判断
[ -f weizhi.sh ] && echo "是一个文件"

[ -f weizhi.sh ] || echo "不是一个文件"
不是一个文件

[ -d weizhi.sh ] || echo "不是一个目录"
不是一个目录

[ -d /tmp ] && echo "是一个目录"
是一个目录

# 实践2-文件权限判断
[ -x memory_info.sh ] || echo "文件没有执行权限"
文件没有执行权限

[ -x memory_info.sh ] || chmod +x memory_info.sh

[ -x memory_info.sh ] && ./memory_info.sh
test 内存使用信息统计
==========================================
内存总量:      972
内存使用量:    266
内存空闲量:    113
内存使用比率:  27.36
内存空闲利率:  11.62
==========================================

# 实践3-文件存在判断

# 文件内容空值判断
touch nihao.txt

[ -s nihao.txt ] || echo "文件为空"
文件为空

echo nihao > file.txt

[ -s file.txt ] && echo "文件不为空"
文件不为空

# 文件存在与否判断
[ -e file.txt ] && echo "文件存在"
文件存在

[ -e file.txt1 ] || echo "文件不存在"
文件不存在

数字表达式

主要根据给定的两个值,判断第一个与第二个数的关系,如是否大于、小于、等于第二个数

语法解读

  • n1 -eq n2 相等
  • n1 -ne n2 不等于
  • n1 -ge n2 大于等于
  • n1 -gt n2 大于
  • n1 -lt n2 小于
  • n1 -le n2 小于等于

简单实践

# 实践1-命令实践
[ 3 -gt 2 ] && echo "3 大于 2"
3 大于 2

[ 3 -ne 2 ] && echo "3 不等于 2"
3 不等于 2

[ 3 -eq 3 ] && echo "3 等于 3"
3 等于 3

实践2-脚本安全

test_argnum.sh,创建脚本文件,内容如下

#!/bin/bash
# -eq 和 -ne 演示

# 设定普通变量
arg_num=$#

[ $arg_num -eq 1 ] && echo "脚本参数为1,允许执行脚本"
[ $arg_num -ne 1 ] && echo "脚本参数不为1,不允许执行脚本"
/bin/bash test_argnum.sh
脚本参数不为1,不允许执行脚本

/bin/bash test_argnum.sh 1
脚本参数为1,允许执行脚本

/bin/bash test_argnum.sh 1 2
脚本参数不为1,不允许执行脚本

表达式进阶

[[]] 测试进阶

我们之前学习过 test 和 [ ] 测试表达式,这些简单的测试表达式,仅仅支持单条件的测试。如果需要针对多条件测试场景的话,我们就需要学习[[ ]] 测试表达式了。我们可以将 [[ ]] 理解为增强版的 [ ],它不仅仅支持多表达式,还支持扩展正则表达式和通配符

语法解析

基本格式:[[ 源内容 操作符 匹配内容 ]]

操作符解析:== 左侧源内容可以被右侧表达式精确匹配,=~ 左侧源内容可以被右侧表达式模糊匹配。==和=~ 都支持正则表达式,=~相当于在匹配字符前后都添加了*,来进行模糊匹配,一般都使用==加正则进行模糊匹配,=~用的很少

简单实践

# 实践1-内容的基本匹配

# 定制默认的的变量
string=value
[[ $string == value ]]

echo $?
0

# [[]] 支持通配符
[[ $string == v* ]]

echo $?
0

# 使用""取消正则,则内容匹配失败
[[ $string == v"*" ]]

echo $?
1

# 使用\取消正则,则内容匹配失败
[[ $string == v\* ]]

echo $?
1

# 实践2-文件的匹配

# 定制文件名称
script_name=file.sh
[[ $script_name == *.sh ]]

echo $?
0

# 尝试其他匹配
[[ $script_name == *.txt ]]

echo $?
1

[[ $script_name != *.txt ]]

echo $?
0

集合基础

所谓的集合,主要是针对多个条件表达式组合后的结果,尤其是针对于逻辑场景的组合。初中数学的相关逻辑示意图:

image.png

表现样式

  1. 两个条件,1 - 真,0 - 假,注意:这里的 0 和 1 ,千万不要与条件表达式的状态值混淆

  2. 三种情况,与 - &,或 - |,非 - !

  3. 与关系

    • 0 与 0 = 0 ,0 & 0 = 0
    • 0 与 1 = 0,0 & 1 = 0
    • 1 与 0 = 0,1 & 0 = 0
    • 1 与 1 = 1,1 & 1 = 1
  4. 或关系

    • 0 或 0 = 0,0 | 0 = 0
    • 0 或 1 = 1,0 | 1 = 1
    • 1 或 0 = 1,1 | 0 = 1
    • 1 或 1 = 1,1 | 1 = 1
  5. 非关系

    非 1 = 0,! true = false

    非 0 = 1,! false = true

简单实践

# 实践1- 简单判断

# 或实践
echo $[ 0 | 1 ]
1

echo $[ 0 | 0 ]
0

echo $[ 1 | 0 ]
1

echo $[ 1 | 1 ]
1

# 与实践
echo $[ 1 & 1 ]
1

echo $[ 1 & 0 ]
0

echo $[ 0 & 1 ]
0

echo $[ 0 & 0 ]
0

# 非实践
true
echo $?
0

false
echo $?
1

echo $[ ! 0 ]
1

echo $[ ! 1 ]
0

逻辑组合

所谓的条件组合,指的是在同一个场景下的多个条件的综合判断效果

语法解析

  1. 方法1
    • [ 条件1 -a 条件2 ] 两个条件都为真,整体为真,否则为假
    • [ 条件1 -o 条件2 ] 两个条件都为假,整体为假,否则为真
  2. 方法2
    • [[ 条件1 && 条件2 ]] 两个条件都为真,整体为真,否则为假
    • [[ 条件1 || 条件2 ]] 两个条件都为假,整体为假,否则为真

简单实践

# 实践1-[]组合实践
user=root pass=123456
[ $user == "root" -a $pass == "123456" ]
echo $?
0

[ $user == "root" -a $pass == "1234567" ]
echo $?
1

[ $user == "root" -o $pass == "1234567" ]
echo $?
0

[ $user == "root1" -o $pass == "1234567" ]
echo $?
1

# 实践2 - [[]]组合实践
[[ $user == "root" && $pass == "123456" ]]
echo $?
0

[[ $user == "root" && $pass == "1234567" ]]
echo $?
1

[[ $user == "root" || $pass == "1234567" ]]
echo $?
0

[[ $user == "root1" || $pass == "1234567" ]]
echo $?
1

综合实践

堡垒机登录

simple_jumpserver.sh,脚本功能-扩充用户名和密码验证功能,创建脚本文件,内容如下

#!/bin/bash
# 功能:定制堡垒机的展示页面
# 版本:v0.3
# 作者:example
# 联系:www.example.com

# 定制普通变量
login_user='root'
login_pass='123456'

# 堡垒机的信息提示
echo -e "\e[31m \t\t 欢迎使用堡垒机"
echo -e "\e[32m
-----------请选择你要登录的远程主机-----------
 1: 10.0.0.14 (nginx)
 2: 10.0.0.15 (tomcat)
 3: 10.0.0.19 (apache)
 q: 使用本地主机
----------------------------------------------
"'\033[0m'

# 由于暂时没有学习条件判断,所以暂时选择 q
read -p "请输入您要选择的远程主机编号: " host_index
read -p "请输入登录本地主机的用户名: " user
read -s -p "请输入登录本地主机的密码: " password
echo
# 远程连接主机
[[ ${user} == ${login_user} && ${password} == ${login_pass} ]] && echo "主机登录验证成功" || echo "您输入的用户名或密码有误"
/bin/bash simple_jumpserver.sh
                 欢迎使用堡垒机

-----------请选择你要登录的远程主机-----------
 1: 10.0.0.14 (nginx)
 2: 10.0.0.15 (tomcat)
 3: 10.0.0.19 (apache)
 q: 使用本地主机
----------------------------------------------

请输入您要选择的远程主机编号: q
请输入登录本地主机的用户名: root
请输入登录本地主机的密码:
主机登录验证成功

/bin/bash simple_jumpserver.sh
                 欢迎使用堡垒机

-----------请选择你要登录的远程主机-----------
 1: 10.0.0.14 (nginx)
 2: 10.0.0.15 (tomcat)
 3: 10.0.0.19 (apache)
 q: 使用本地主机
----------------------------------------------

请输入您要选择的远程主机编号: q
请输入登录本地主机的用户名: root1
请输入登录本地主机的密码:
您输入的用户名或密码有误

信息检测

脚本功能-检测公司网站的存活

# 判断网站的命令
# --spider 不下载,-T5 超时时间5秒,-q 关闭wget的输出,-t2 重试次数为2
wget --spider -T5 -q -t2 www.baidu.com
echo $?
0

wget --spider -T5 -q -t2 www.baidu.com1
echo $?
4
# -s 不显示进度或错误,-o /dev/null 指定输出到/dev/null即抑制输出
curl -s -o /dev/null www.baidu.com
echo $?
0

curl -s -o /dev/null www.baidu.com1
echo $?
6

site_healthcheck.sh,创建脚本文件,内容如下

#!/bin/bash
# 功能:定制站点的检测功能
# 版本:v0.1
# 作者:example
# 联系:www.example.com

# 定制普通变量
site_addr="$1"
# 脚本基本判断
[ -z ${site_addr} ] && echo "请输入待测试站点域名" && exit
[ $# -ne 1 ] && echo "请保证输入1个脚本参数" && exit

# 检测平台的信息提示
echo -e "\e[32m-----------检测平台支持的检测类型-----------
 1: wget
 2: curl
----------------------------------------"'\033[0m'

# 选择检测类型
read -p "请输入网站的检测方法: " check_type
if [ ${check_type} == 1 ]; then
  site_status=$([ ${check_type} == 1 ] && wget --spider -T5 -q -t2 ${site_addr} && echo "正常" || echo "异常") 
else
  site_status=$([ ${check_type} == 2 ] && curl -s -o /dev/null ${site_addr} && echo "正常" || echo "异常")
fi
# 信息输出
echo
echo -e "\e[31m\t站点状态信息\e[0m"
echo -e "\e[32m================================"
echo "${site_addr} 站点状态: ${site_status}"
echo -e "================================\e[0m"
/bin/bash site_healthcheck.sh
请输入待测试站点域名

/bin/bash site_healthcheck.sh aa bb
请保证输入1个脚本参数

/bin/bash site_healthcheck.sh www.baidu.com
-----------检测平台支持的检测类型-----------
 1: wget
 2: curl
----------------------------------------
请输入网站的检测方法: 1

        站点状态信息
================================
www.baidu.com 站点状态: 正常
================================

/bin/bash site_healthcheck.sh www.baidu.com1
-----------检测平台支持的检测类型-----------
 1: wget
 2: curl
----------------------------------------
请输入网站的检测方法: 2

        站点状态信息
================================
www.baidu.com1 站点状态: 异常
================================