Shell之条件语句

编程入门 行业动态 更新时间:2024-10-10 19:18:22

Shell之条件<a href=https://www.elefans.com/category/jswz/34/1770772.html style=语句"/>

Shell之条件语句

条件语句

  • 测试
    • 比较整数数值
    • 字符串比较
      • 常用的测试操作符
    • 逻辑测试(短路运算)
    • 双中括号
    • (){}
  • if语句的结构
    • 分支结构
    • case
    • echo

测试

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" ]
thenecho "非管理员用户无权限操作"
else
echo "是管理员用户"
fi###########判断是主机连通性#######################       
#!/bin/bash
ping -c 3 192.168.91.1
if[ $? = 0 ]
thenecho "与真机网络通顺"exit 1
fiecho "与真机网络不通"#######################多分支####################### 
#!/bin/bash
read -p "请输入你的考试分数:" gradeif [ $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 ;;]... esaccase 变量引用 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"   #前三天  
2023年 02月 02日 星期四 10:08:32 CST
[root@localhost ~]# date -d "+3 day"   #后三天
2023年 02月 08日 星期三 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  63  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  54  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 3030 31七月                   八月                   九月        
日 一 二 三 四 五 六   日 一 二 三 四 五 六   日 一 二 三 四 五 六1  2  3    1  2  3  4  5  6  7             1  2  3  44  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  43  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’` 

更多推荐

Shell之条件语句

本文发布于:2024-02-06 04:56:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1746798.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:语句   条件   Shell

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!