4、shell if case while for

2019-12-21  本文已影响0人  沙砾丶ye

Shell__逻辑结构

一、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和nginx 服务"
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

实战案例

服务状态检测工具

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

[root@localhost ~]# sh fuwu.sh
输入一个常用的服务默认端口:80
http和nginx 服务

在判断中支持正则

使用双中括号 [[ ]]

匹配 使用 =~
比如: [[ "$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

二、 利用 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
        ;;
*)
        echo "Invalid input"
        ;;
esac

服务端口查询

#!/bin/bash
read -p "输入你想查询的端口号" hao
case $hao in
"80")
   echo "httpd和nginx 服务"
     ;;
"3306")
    echo "mksql 服务"
     ;;
"8080")
    echo "tomcat 服务"
     ;;
"9000")
   echo "php 服务"
    ;;
"22")
   echo "sshd 服务"
    ;;
"21")
    echo "ftp 服务"
    ;;
"23")
    echo "telnet 服务"
   ;;
esac

三、while ... do ... 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

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

image.png
for 循环中 变量的取值方式

1、从一组字符串中取值

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

2、从位置变量中取值

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

执行方式

sh bianliang.sh 1 2

输出结果

------------------------
$var   is      1
------------------------
$var   is       2

3、累计变化的格式中取值

#!/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

实例

九九乘法表

#!/bin/bash
for i in {1..9}
do
          for j in {1..9}
          do
                if [ $j -le $i ]
                then
                echo -n " $j*$i=$((j*i)) "
               fi
         done
echo ""
done

执行结果

[root@localhost ~]# sh chengfa.sh
 1*1=1 
 1*2=2  2*2=4 
 1*3=3  2*3=6  3*3=9 
 1*4=4  2*4=8  3*4=12  4*4=16 
 1*5=5  2*5=10  3*5=15  4*5=20  5*5=25 
 1*6=6  2*6=12  3*6=18  4*6=24  5*6=30  6*6=36 
 1*7=7  2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49 
 1*8=8  2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64 
 1*9=9  2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81 

删除指定目录下的空文件

#!/bin/bash
read -p "输入你想要删除的目录" mulu
cd $mulu
for i in `ls`
do
       if [ -f $i ]
       then
           if [ ! -s $i ]
            then
                rm -rf $i
            fi
      fi
 done

补充:数值运算

 ➜  ~ 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
运行结果

2. 单层循环的 continue
示例代码

image.png
执行结果
image.png

3. 多层循环的 break

示例代码

image.png
执行结果
image.png
上一篇下一篇

猜你喜欢

热点阅读