Shell之条件语句

测试

test 测试文件的表达式 是否成立

Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0时表示成功,否则(非0值)表示失败或异常。

test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值为0表示条件成立)。

格式1: test 条件表达式
格式2: [ 条件表达式 ]
注意[]空格,否则会失败
测试 是否成功使用 $? 返回值
[ 操作符 文件或目录 ]
help test

操作符

操作符含义
-d测试是否为目录(Directory)
-e测试目录或文件是否存在(Exist)
-a测试目录或文件是否存在(Exist)
-f测试是否为文件(File)
-r测试当前用户是否有权限读取(Read)
-w测试当前用户是否有权限写入(Write)
-x测试当前用户是否有权限执行(eXcute)
-L测试是否为软连接文件

属性测试补充

属性含义
-sFILE #是否存在且非空
-tfd #fd 文件描述符是否在某终端已经打开
-NFILE #文件自从上一次被读取之后是否被修改过
-OFILE #当前有效用户是否为文件属主
-GFILE #当前有效用户是否为文件属组

条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成

测试过程,实现评估布尔声明,以便用在条件性环境下进行执行

若真,则状态码变量 $? 返回0

若假,则状态码变量 $? 返回1

条件测试命令

比较整数数值

[ 整数1 操作符 整数2 ] 公式

  • -eq:第一个数等于(Equal)第二个数
  • -ne:第一个数不等于(Not Equal)第二个数
  • -gt:第一个数大于(Greater Than)第二个数
  • -lt:第一个数小于(Lesser Than)第二个数
  • -le:第一个数小于或等于(Lesser or Equal)第二个数
  • -ge:第一个数大于或等于(Greater or Equal)第二个数

实例:

[root@test1 ~]# a=2        
[root@test1 ~]# b=3
[root@test1 ~] [ $a -eq $b ]
[root@test1 ~]# echo $?
1
[root@test1 ~]# [ 2 -le 3 ]
[root@test1 ~]# echo $?
0

在这里插入图片描述

字符串比较

常用的测试操作符

  • =:字符串内容相同
  • !=:字符串内容不同,! 号表示相反的意思
  • -z:字符串内容为空
  • -n: 字符是否存在

格式

[  字符串1  =  字符串2 ]  是否相同

[  字符串1  !=  字符串2 ]  是否不相同

[  -z  字符串 ]   是否为空

[  -n  字符串 ] 字符是否存在

实例:

[root@localhost ~]# str1=wang
[root@localhost ~]# str2=zhou
[root@localhost ~]# [ $str1 = $str2 ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ $USER = root ]&& echo true
true
[root@localhost ~]# [ $USER != root ]&& echo true
[root@localhost ~]# read -p "yes/no:" ack
yes/no:yes
[root@localhost ~]# echo $ack 
yes
[root@localhost ~]# [ -z $ack ] && echo true 
[root@localhost ~]# read -p "是否覆盖当前文件 (yes/no)" ACK
是否覆盖当前文件 (yes/no)yes
[root@localhost ~]# [ $ACK = "yes" ] && echo "覆盖"
覆盖
[root@localhost ~]# read -p "是否覆盖当前文件 (yes/no)" ACK
是否覆盖当前文件 (yes/no)yes
[root@localhost ~]# [ $ACK = "no" ] && echo "不覆盖"

在这里插入图片描述

逻辑测试(短路运算)

格式

格式1[  表达式1  ]  操作符  [  表达式2  ]  ... 
格式2:命令1  操作符  命令2  ... 

常见条件:

  • -a或&&:逻辑与,“而且”的意思全真才为真
  • -o或||:逻辑或,“或者”的意思一真即为真
  • !:逻辑否

(1)短路与 &&

CMD1 短路与 CMD2      &&   同时满足命令1 和命令2 的要求  才会返回正确
全真才为真  一假即为假      
第一个CMD1结果为真 ,第二个CMD2必须要参与运算,才能得到最终的结果 
第一个CMD1结果为假 ,总的结果必定为假,因此不需要执行CMD2

(2)短路或 ||

CMD1 短路或 CMD2
一真即为真
第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2
第一个CMD1结果为假 (0),第二个CMD2 必须要参与运算,才能得到最终的结果

实例:

[root@localhost ~]# uname -r 
3.10.0-693.el7.x86_64
[root@localhost ~]# uname -r |awk -F. '{print $1}'
3
[root@localhost ~]# uname -r |awk -F. '{print $2}'
10
[root@localhost ~]# MAIN=$(uname -r |awk -F. '{print $2}')
[root@localhost ~]# SAIN=$(uname -r |awk -F. '{print $1}')
[root@localhost ~]# [ $SAIN -ge 3 ]&& [ $MAIN -ge 4 ]&& echo "yes"
yes
[root@localhost ~]# [ ! -d mmm ] && echo "yes"
yes
[root@localhost ~]# [ 4 -lt 5 ]&&echo true || echo false
true
[root@localhost ~]# [ 4 -gt 5 ]&&echo true || echo false
false
[root@localhost ~]# [ 4 -gt 5 ]&& echo true ||echo false
false

|| 只有前面不成立时才会执行后面的操作

在这里插入图片描述

双中括号

[[ expression ]] 用法
== 左侧字符串是否和右侧的PATTERN相同
 注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
 注意: 此表达式用于[[ ]]中;扩展的正则表达式

实例:

[root@localhost ~]# FILE=test.log
[root@localhost ~]# [[ "$FILE" == *.log ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# FILE=test.txt
[root@localhost ~]# [[ "$FILE" == *.log ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [[ "$FILE" != *.log ]]
[root@localhost ~]# echo $?
0

在这里插入图片描述

(){}

(CMD1;CMD2;…)和 {空格CMD1;CMD2;…; } 都可以将多个命令组合在一起,批量执行

实例:

[root@localhost ~]# ( cd /data;ls )
test.txt
[root@localhost ~]# pwd
/root
[root@localhost ~]# { cd /data;ls; }
test.txt
[root@localhost data]# pwd
/data


#()会开启子shell
[root@localhost ~]# echo $BASHPID
3839
[root@localhost ~]# ( echo $BASHPID;sleep 100)
4016
^C
[root@localhost ~]# pstree -p
systemd(1)─┬─ModemManager(719)─┬─{ModemManager}(757)
           │                   └─{ModemManager}(792)
           ├─NetworkManager(868)─┬─{NetworkManager}(883)
           │                     └─{NetworkManager}(885)
           ├─VGAuthService(726)
           ├─abrt-watch-log(723)
           ├─abrtd(721)
           ├─accounts-daemon(734)─┬─{accounts-daemon}(755)
           │                      └─{accounts-daemon}(791)
           ├─alsactl(720)
           ├─anacron(3950)
.......................................

#{ } 不会开启子shell
[root@localhost ~]# echo $BASHPID
3839
[root@localhost ~]# { echo $BASHPID; }
3839


[root@localhost ~]# name=lc
[root@localhost ~]# ( name=mcl;echo $name );echo $name
mcl
lc
[root@localhost ~]# name=lc
[root@localhost ~]# { name=mcl;echo $name; };echo $name
mcl
mcl

在这里插入图片描述

if语句的结构

分支结构

单分支

if 判断条件;

then   条件为真的分支代码

fi

双分支

if 判断条件; then
 条件为真的分支代码

else
 条件为假的分支代码

fi

多分支

if 判断条件1
then
 条件1为真的分支代码

elif 判断条件2
then
 条件2为真的分支代码

elif 判断条件3;then
 条件3为真的分支代码

...
else
 以上条件都为假的分支代码

fi

实例:

#单分支

###########判断是否为超级管理员#######################
#!/bin/bash
if [ "$USER" != "root" ]
then
        echo "非管理员用户无权限操作"
else
echo "是管理员用户"
fi

###########判断是主机连通性#######################       
#!/bin/bash
ping -c 3 192.168.91.1
if
        [ $? = 0 ]
then
        echo "与真机网络通顺"
        exit 1
fi
        echo "与真机网络不通"
        
        
#######################多分支####################### 
#!/bin/bash
read -p "请输入你的考试分数:" grade

if [ $grade -ge 85 ]&& [ $grade -le 100 ]
then
echo "你的成绩为$grade"
echo "你的成绩为优秀"

elif [ $grade -ge 70 ]&&[ $grade -le 84 ]
then
echo "你的成绩为$grade"
echo "你的成绩为良好"
elif
[ $grade -ge 60 ]&&[ $grade -le 69 ]
then
echo "你的成绩为$grade"
echo "你的成绩为合格" 
else
echo "你的成绩为$grade"
echo "你的成绩不合格"
fi


#!/bin/bash
h=`date +%H`
if [ $h -ge 6 -a $h -le 10 ];then
echo "早上好"
elif [ $h -ge 11 -a $h -le 13 ];then
echo "中午好"
elif [ $h -ge 14 -a $h -le 18 ];then
echo "下午好"
else
echo "晚上好"
fi

case

格式

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac

case 变量引用 in
PAT1)
 分支1
 ;;
PAT2)
 分支2
 ;;
...
*)
 默认分支
 ;;


case支持glob风格的通配符:
* 任意长度任意字符
? 任意单个字符
[0-9] 指定范围内的任意单个字符
|   或者,如: a|b

echo

实例:

echo -n   表示不换行输出
echo -e   表示输出转义符
常用的转义符

选项作用
选项
--------
\r光标移至行首,并且不换行
\s当前shell的名称,如bash
\t插入Tab键,制表符
\n输出换行
\f换行,但光标仍停留在原处
\表示插入"\"本身转义
\b表示退格 不显示前一个字符
\c抑制更多的输出或不换行

实例:

[root@localhost ~]# echo -e "12345\b678"  ##退格删除前面的字符
1234678
[root@localhost ~]# echo -e "12345\b\b678"
123678
[root@localhost ~]# echo -e "12345\b\b\b678"
12678
[root@localhost ~]# echo -e "12345\b\b\b\b678"
16785
###注意退格键和末尾的字符相关,超过末尾的字符数量 会出bug 了解即可

[root@localhost ~]# echo -e "12345678\c"
12345678[root@localhost ~]# echo -e "1234\c5678"
1234[root@localhost ~]# 

###\c 注意 使用在数字中间会把后面内容删除

在这里插入图片描述
date
date查看当前系统时间

-d 你描述的日期,显示指定字符串所描述的时间,而非当前时间

%F 完整日期格式,等价于 %Y-%m-%d

% T 时间(24小时制)(hh:mm:ss)

实例:

[root@localhost ~]# date -d '-1 day' +%F 
2023-02-04
[root@localhost ~]# date  +%F 
2023-02-05
[root@localhost ~]#  date -d '1 day ' +%F-%T
2023-02-06-10:08:17
[root@localhost ~]# date -d "-3 day"   #前三天  
20230202日 星期四 10:08:32 CST
[root@localhost ~]# date -d "+3 day"   #后三天
20230208日 星期三 10:08:40 CST
[root@localhost ~]# date -d '1 day ' +%F'     '%T
2023-02-06     10:08:49
[root@localhost ~]# cal 2021 #查看日历
                               2021                               

        一月                   二月                   三月        
日 一 二 三 四 五 六   日 一 二 三 四 五 六   日 一 二 三 四 五 六
                1  2       1  2  3  4  5  6       1  2  3  4  5  6
 3  4  5  6  7  8  9    7  8  9 10 11 12 13    7  8  9 10 11 12 13
10 11 12 13 14 15 16   14 15 16 17 18 19 20   14 15 16 17 18 19 20
17 18 19 20 21 22 23   21 22 23 24 25 26 27   21 22 23 24 25 26 27
24 25 26 27 28 29 30   28                     28 29 30 31
31
        四月                   五月                   六月        
日 一 二 三 四 五 六   日 一 二 三 四 五 六   日 一 二 三 四 五 六
             1  2  3                      1          1  2  3  4  5
 4  5  6  7  8  9 10    2  3  4  5  6  7  8    6  7  8  9 10 11 12
11 12 13 14 15 16 17    9 10 11 12 13 14 15   13 14 15 16 17 18 19
18 19 20 21 22 23 24   16 17 18 19 20 21 22   20 21 22 23 24 25 26
25 26 27 28 29 30      23 24 25 26 27 28 29   27 28 29 30
                       30 31
        七月                   八月                   九月        
日 一 二 三 四 五 六   日 一 二 三 四 五 六   日 一 二 三 四 五 六
             1  2  3    1  2  3  4  5  6  7             1  2  3  4
 4  5  6  7  8  9 10    8  9 10 11 12 13 14    5  6  7  8  9 10 11
11 12 13 14 15 16 17   15 16 17 18 19 20 21   12 13 14 15 16 17 18
18 19 20 21 22 23 24   22 23 24 25 26 27 28   19 20 21 22 23 24 25
25 26 27 28 29 30 31   29 30 31               26 27 28 29 30

        十月                  十一月                 十二月       
日 一 二 三 四 五 六   日 一 二 三 四 五 六   日 一 二 三 四 五 六
                1  2       1  2  3  4  5  6             1  2  3  4
 3  4  5  6  7  8  9    7  8  9 10 11 12 13    5  6  7  8  9 10 11
10 11 12 13 14 15 16   14 15 16 17 18 19 20   12 13 14 15 16 17 18
17 18 19 20 21 22 23   21 22 23 24 25 26 27   19 20 21 22 23 24 25
24 25 26 27 28 29 30   28 29 30               26 27 28 29 30 31
31


[root@localhost ~]# cal 9 1752
      九月 1752     
日 一 二 三 四 五 六
       1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30


***
crontab  里 不能有 %30 2 * * * /bin/cp -a /etc/ /data/etc`date +\%F_\%T`
30 2 * * * /bin/cp -a /etc/ /data/etc`date +%F_%T’` 

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值