美文网首页
五、shell逻辑结构

五、shell逻辑结构

作者: 胖虎喜欢小红 | 来源:发表于2019-12-20 18:45 被阅读0次

一、if 判断

if ... then ... fi

如果...那么...

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

示例:

#!/usr/bin/env sh
read -p "请输入一个整数:" num

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

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

如果...那么...否则...

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

示例:

#!/usr/bin/bash
 read -p "please input ip : " ip
 ping -c1 $ip &>/dev/null
 if [ $? -eq 0 ];then
     echo "$ip is up."
 else
     echo "$ip is down!"
 fi

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

如果...又如果...又如果...否则...

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

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

示例

    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/bash
read -p "please input port name : " port
if [[ "$port" =~ [0-9]+ ]];then
    if [ "$port" -eq 80 ];then
        echo "this is HTTP service"
    elif [ "$port" -eq 3306 ];then
        echo "this is Mysql service"
    elif [ "$port" -eq 20 ] || [ "$port" -eq 21 ];then
        echo "this is FTP service"
    fi
fi

while ... do ... done (不确定循环)

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

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

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

#!/usr/bin/bash
n=0
while [ $n -le 5 ]
    do
        read -p "please input a number : " num
        if [ $num -eq 18 ];then
            echo "nice"
        break
        elif [ $num -gt 18 ];then
            echo "You put in a big number"
        elif [ $num -lt 18 ];then
            echo "The number you entered is smaller"
        fi
    let n++
done

读文件

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

计数

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

ps aux 示例

#!/usr/bin/bash
servername=$1
ps aux | grep -v "$0" | grep -v "grep" | grep "$servername" &>/dev/null
if [ "$?" -eq 0 ];then
    echo "$1 service is up"
else
    echo "$1 service is down"
fi

ping

#!/usr/bin/bash
while [ ture ]
do
read -p "please input ip : " ip
if [[ $ip =~ [0-9]+ ]];then
ping -c1 $ip &>/dev/null
else
    echo "error. ip is number."
    break
fi
if [ $? -eq 0 ];then
    echo "$ip is up."
else
    echo "$ip is down!"
fi
done

利用 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

for do done (固定的循环)

语法
for var in con1 con2 con3 ...
do
    程序段
done

for a in 1 2 3 4
do
echo "$a"
done

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

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

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

for 循环中 变量的取值方式

a. 从一组字符串中取值

for a in 1 2 3 4
do
echo "$a"
done

b. 从位置变量中取值

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

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

#!/bin/bash 

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

d. 从命令结果中取值

#!/bin/bash
for var in $(cat -n /etc/passwd)
do
    echo " ------------------------" 
    echo '$var   is' $var
done

IFS

修改 for 循环中的分界符,默认是 空格
示例 a.txt 文件的内容
ifs可以定义任意的字符为分隔符

# 先保存原来的值
old_ifs=$IFS

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

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

!/usr/bin/bash
oldIFS=${IFS}
IFS=$'\n'
for a in $(cat -n /etc/passwd)
do
echo "$a"
done
export IFS=${oldIFS}

循环嵌套

for n in {1..3}
do
    for i in {a..e}
    do
        echo "外层循环的值$n--内层循环的值$i"
    done
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 就是退出循环,循环不再继续了。假如是嵌套的循环,就是退出当前层级的循环。
  • break 后面可以接想跳出的层数
  • continue 是停止本次循环体内的代码,继续进行下一次循环。

单层break

for n in {1..5}
do
    if [ $n -eq 3 ];then
        echo "out"
        break
    fi
    echo "$n"
done
    echo "out $n"

单层continue

for n in {a..f}
do
    if [ $n == d ];then
    echo "out"
    continue
    fi
    echo "$n"
done
echo "$n over"

双层continue

for a in {1..5}
do
    for b in {a..f}
    do
    if [ $b == c ];then
    echo "out"
    continue
    fi
        echo "$b"
    done
        echo "$a"
        echo "========"
done

相关文章

网友评论

      本文标题:五、shell逻辑结构

      本文链接:https://www.haomeiwen.com/subject/iliinctx.html