Shell_6_逻辑结构

https://www.jianshu.com/p/3557bf2da86a

一、if 判断

if ... then ... fi

单层
如果 是真的 那么 ...

if [ 条件判断式 ];then
    当条件判断式成立时,可以进行的命令。
fi   # 结束这个判断语句结构

示例:
提示输入一个整数,程序判断输入的值是否大于 18

风格 1

#!/usr/bin/env sh

read -p "请输入一个整数:" num

if [ "$num" -gt 18 ];then
    echo "你输入的数值大于 18"
fi

echo "hello..."

风格2

#!/usr/bin/env sh

read -p "请输入一个整数:" num

if [ "$num" -gt 18 ]
then
    echo "你输入的数值大于 18"
fi

echo "hello..."

if ... then ... else....fi

多重、复杂条件判断式
如果 是真的 那么 ... 否则 ...

一颗红心,两手准备

if [ 条件判断式 ]; then
    当条件判断式成立时,可以进行的指令工作内容;
else
    当条件判断式不成立时,可以进行的指令工作内容;
fi

示例:

判断用户输出的字符串
输入 y
就输出文本内容 "script is running..."
否则输出文本内容 "STOP"

image.png

if ... elif ... elif ... else ... fi

多个条件判断 (if ... elif ... elif ... else) 分多种不同情况执行


if [ 条件判断式一 ]; then
    当条件判断式一成立时,可以进行的指令工作内容;
elif [ 条件判断式二 ]; then
    当条件判断式二成立时,可以进行的指令工作内容;
else
    当条件判断式一与二均不成立时,可以进行的指令工作内容;
fi

注意
elif 也是个判断式,因此出现 elif 后面都要接 then 来处理!但是 else 已经是最后的没有成立的结果了, 所以 else 后面并没有 then

示例

通过判断输入的整数,判断是什么常用服务

#!/usr/bin/env sh
read -p "请输入一个常用的服务默认端口号:"  port

if [ "$port" -eq 80 ];then
    echo "HTTP 服务"
elif [ "$port" -eq 3306 ];then
    echo "Mysql 服务"
elif [ "$port"  -eq  21 ] || [ "$port"  -eq  20 ];then
    echo "FTP 服务"
elif [ "$port" -eq 22 ];then
    echo "SSHD 服务"
elif [ "$port"  -eq 23 ];then
    echo "Telnet 服务"
else
   echo "未知服务"
fi

实战案例

服务状态检测工具

通过获取目前系统中的服务进程,判断都有那些服务处于运行状态


在判断中支持正则

使用双中括号 [[ ]]

  • 匹配 使用 =~

比如: [[ "$val" =~ [a-z]+ ]]

=~ 表示 匹配
[a-z]+ 是正表达式,不需要用任何引号,用了引号就会被识别为普通字符串

  • 不匹配 使用 !

比如: [[ ! "$val" =~ [0-9]+ ]]

示例

#!/usr/bin/env   sh
name=shark

if [[ "$name"  =~  [a-z]+ ]];then
   echo "ok"
fi


if [[ ! "$name" =~ [0-9]+ ]];then
   echo  "good"
fi

嵌套

#!/usr/bin/env sh
read -p "请输入一个常用的服务默认端口号:"  port

if [[ "$port" =~ [0-9]+ ]];then

    if [ "$port" -eq 80 ];then
        echo "HTTP 服务"
    elif [ "$port" -eq 3306 ];then
        echo "Mysql 服务"
    elif [ "$port"  -eq  21 ] || [ "$port"  -eq  20 ];then
        echo "FTP 服务"
    elif [ "$port" -eq 22 ];then
        echo "SSHD 服务"
    elif [ "$port"  -eq 23 ];then
        echo "Telnet 服务"
    else
       echo "未知服务"
    fi
else
    echo "nmber"
fi
image.png

二、 利用 case ..... esac 判断

基本语法

case  $变量名称 in       <==关键字为 case ,还有变量前有钱字号
  "第一个变量的值")       <==每个变量内容建议用双引号括起来,关键字则为小括号 )
    程序段
    ;;                  <==每个类别结尾使用两个连续的分号来处理!
  "第二个变量的值")
    程序段
    ;;
  *)                    <==最后一个变量内容都会用 * 来代表所有其他值
    不包含第一个变量内容与第二个变量内容的其他程序运行段
    exit 1
    ;;
esac                    <==反过来写,结束当前语句结构!

运维工具箱


========================================================

模式还可以是多个

#!/bin/bash
cat << EOF
m|M) show memory usages;
d|D) show disk usages;
q|Q) quit
EOF
read -p "Your choice" choice
case $choice in
m|M)
        free -m
        ;;
d|D)
        df -h
        ;;
q|Q)
        exit
        ;;
*)
        eco "Invalid input"
        ;;
esac

三、while ... do ... done (不确定的循环)

while [ condition ]  ==>中括号内的状态就是判断式
do                   ==> do 是循环的开始!
    命令或者代码
    命令或者其他逻辑语句
done                 ==> done 是循环的结束

计数

每次循环体执行完,while 都会检查条件是否为真,为真继续循环,否则终止循环。

n=0
while [ "$n" -lt 5 ]
do
   let n++
   echo "$n"
done

读文件

while read line
do
    echo $line
done < /etc/passwd

每次循环, 都会把 /etc/passwd 中的每一个行内容 赋值给变量 line

read

[root@sharkyun ~]# read id name age
1 shark 18
[root@sharkyun ~]# echo $age
18
[root@sharkyun ~]# echo $id  $name
1 shark

[root@sharkyun ~]# old_ifs=$IFS; IFS=','
[root@sharkyun ~]# read id name age
2, xiguatian, 20
[root@sharkyun ~]# echo "$id| $name| $age"
2|  xiguatian|  20
[root@sharkyun ~]# export IFS=$old_ifs
[root@sharkyun ~]# read id name age
2, xiguatian, 20
[root@sharkyun ~]# echo "$id| $name| $age"
2,| xiguatian,| 20
[root@sharkyun ~]# read id name age
2,xiguatian,20
[root@sharkyun ~]# echo "$id| $name| $age"
2,xiguatian,20| |

while read

$ cat db.sql
1 shark 18
2 xiguatian 20

$ cat  while-read-m.sh
while read id name age
do
    echo "$id | $name | $age"
done < db.sql

$ sh while-read-m.sh

1 | shark | 18
2 | xiguatian | 20

五、 for do done (固定的循环)

var 是变量名
con1 con2 con3 是常量,就是具体的数据
也可以是一个已经被赋值的变量, 写法 ${v1} ${v2}

以上面的例子来说,这个 $var 的变量内容在循环工作时会动态的改变:

  1. 第一次循环时, $var 的内容为 con1 ;
  2. 第二次循环时, $var 的内容为 con2 ;
  3. 第三次循环时, $var 的内容为 con3 ;
  4. ....

for 循环中 变量的取值方式

a. 从一组字符串中取值

for  var     in    one    two    three   four   five 
do
    echo    "****************************"
    echo   '$var   is '    $var
done

b. 从位置变量中取值

for    var
do
    echo  '-----------------------------'
    echo   '$var   is '    $var
done

按照如下方式执行:

image.png

c. 从累计变化的格式中取值

#!/bin/bash 

for    ((var=1;var<=10;var++))
do
    echo   "------------------------" 
    echo   '$var   is '    $var
done

d. 从命令结果中取值

#!/bin/bash
for   var   in   $(cat    file.txt)
do
    echo  " ------------------------" 
    echo   '$var   is '    $var
done

IFS

修改 for 循环中的分界符,默认是 空格

示例 a.txt 文件的内容

hello world name age
hello world name age
# 先保存原来的值
old_ifs=$IFS

# 设置分界符为 回车
IFS=$'\n'
for line in $(cat a.txt)
do
  echo $line
done

# 把变量的值回复成原来的状态
export IFS=$old_ifs

嵌套循环

for n in {1..3}
do
    for i in {a..e}
    do
        echo "外层循环的值$n--内层循环的值$i"
    done
    echo "----------------"
done

执行结果

image.png

补充:数值运算

➜  ~ n=1
➜  ~ let n++
➜  ~ echo $n
2
➜  ~ (( n++ ))
➜  ~ echo $n
3
➜  ~ a=2
➜  ~ b=3
➜  ~ let f=a+b
➜  ~ echo $n
3
➜  ~ echo $f
5
➜  ~ let f = a + b     ==> 错误
zsh: bad math expression: operand expected at `='
➜  ~ let "f = a + b"
➜  ~ echo $f
5

六、break 和 continue

  • break 就是退出循环,循环不再继续了。假如是嵌套的循环,就是退出当前层级的循环。

  • continue 是停止本次循环体内的代码,继续进行下一次循环。

1. 单层循环的 break

示例代码

image.png

运行结果

image.png

2. 单层循环的 continue

示例代码

image.png

执行结果

image.png

3. 多层循环的 break

示例代码

image.png

执行结果

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • 流程控制 if 单条件 双分支 多分支 case case支持glob风格的通配符: *: 任意长度任意字符?: ...
    毛利卷卷发阅读 741评论 0 1
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,365评论 0 5
  • 一、if 判断 if ... then ... fi 单层如果 是真的 那么 ... if ... then ...
    互联网中的一个咸鱼阅读 212评论 0 1
  • Bash内置基本变量 PWD : 显示当前的工作目录 OLDPWD : 显示上一次的工作目录 ~:用户家目录 - ...
    魏镇坪阅读 1,512评论 0 6
  • 收获在下个路口 温麻新姿 人的记忆就像一座宁静的水库,闸门一打开,就会奔涌而出。每逢佳节倍思亲,同样睹物也思...
    温麻新姿A阅读 244评论 0 1