shell中的流程控制语句

1、if语句

(1)单分支if条n件语句:

    1)语法:

    if [ 条件判断式 ];then

       动作

    fi

或:

    if [ 条件判断式 ]

then

       动作

    fi

    2)案例:

例1:判断文件是否存在,不存在则创建

#!/bin/sh

path=/root/script/

file=if1.sh

#mkdir

if [ ! -d ${path} ];then

        mkdir -p ${path}

        echo "${path} dir is not exit,already created it"

fi

#touch file

if [ ! -f ${path}${file} ]

  then

        touch ${path}${file}

        echo "${path}${file} is not exit,already created it"

        exit

fi

ls -l  ${path}${file}

例2:判断磁盘使用率最大的分区,大于80%则报警

#!/bin/sh

usate=`df -h | tr -s " " | sort -nr -t" " -k5  | head -1 | awk '{print $5}' | cut -d"%" -f1`

namedev=`df -h | tr -s " " | sort -nr -t" " -k5  | head -1 | awk '{print $1}'`

if [ $usate -ge 80 ];then

    echo "warning! ${namedev} is full"

fi   

例3:新建shell脚本时写入注释信息并进入到第六行

#!/bin/bash

NEWNAME=$1

if ! grep -q "#!" ${NEWNAME} ;then

cat>>${NEWNAME}<<EOF

#!/bin/bash

#

#Author:Nan Li

#Date:`date +%F`

#Version:3.2

#Description:

EOF

fi

 

vim  +6 ${NEWNAME}

(2)双分支if条件语句:

1)语法:

    if [ 条件判断式 ]

 then

       条件成立时,执行该动作

     else

       条件不成立时,执行

    fi

2)案例

例1:备份/etc目录

#!/bin/sh

rate=$(date +%F)

size=$(du -sh /etc)

if [ -d /tmp/etcbak ]

  then

    echo "Date:${rate}" >> /tmp/etcbak/etcinfo.txt

    echo "Date size:${size}" >> /tmp/etcbak/etcifo.txt

    cd /tmp/etcbak

    tar -zcf etc-${rate}.tar.gz /etc etcinfo.txt &>/dev/null

    rm -rf /tmp/etcbak/etcifo.txt

else

    mkdir /tmp/etcbak

    echo "Date:${rate}" >> /tmp/etcbak/etcinfo.txt

    echo "Date size:${size}" >> /tmp/etcbak/etcifo.txt

    cd /tmp/etcbak

    tar -zcf etc-${rate}.tar.gz /etc etcinfo.txt &>/dev/null

    rm -rf /tmp/etcbak/etcifo.txt

fi

例2:(方法1)判断httpd服务是否启动

#!/bin/sh

port=`nmap -sT 172.16.250.102 | grep tcp | grep http | awk '{print $2}'`

if [ "$port" == "open" ]

  then

    echo "$(date +%F-%T) httpd is ok" >> /tmp/autostart-acc.log

  else

    systemctl start httpd &> /dev.null

    echo "$(date +%F-%T) restart httpd!!" >>/tmp/autostart-err.log

fi

(方法2)判断httpd服务是否启动

#!/bin/bash

while true; do

 

COUNT=`ps aux | grep "httpd" | grep -v "grep" | wc -l`

#echo ${COUNT}

if [ ${COUNT} -eq 0 ];then

        systemctl start httpd

        echo "------`date "+%F %T"` server down" >> httpd.log

fi

 

 sleep 60

done

(2)双分支if条件语句:

1)语法:

if [ 条件判断式1 ]

 then

       条件1成立时,执行该动作

     elif [ 条件判断式2 ]

     then

       条件2成立时,执行该动作

elif [ 条件判断式3 ]

then

        条件3成立时,执行该动作

    ……

else

   当所有条件都不成立时,执行该动作

    fi

2)案例

例1:判断两个整数的大小

#!/bin/sh

read -p "please input two number:" a b

#no1

[ -z $a ] || [ -z $b ] && {

  echo "please input two number agcogin"

  exit 1

}

#no 2

expr $a + 0 &>/dev/null

RETVAL1=$?

expr $b + 0 &>/dev/null

RETVAL2=$?

test $RETVAL1 -eq 0 -a $RETVAL2 -eq 0 || {

  echo -e "please input two \033[31m number \033[0m again!!"

  exit 2

}

#no3

if [ $a -lt $b ]

  then

    echo "$a < $b "

  elif [ $a -eq $b ]

  then

    echo "$a = $b"

  else

    echo "$a > $b "

fi

例2:输入一个文件判断是什么文件

#!/bin/sh

read -p "please input one filename:" file

if [ -z $file ]

      then

        echo "error,please input a filename"

        exit 1

   elif [ -f "$file" ]

      then

        echo "$file is a ragulare file"

   elif [ -d "$file" ]

      then

        echo "$file is a directory"

   elif [ -L "$file" ]

      then

        echo "$file is a linkfile"

   else

        echo "sorry i don't know"

fi

2、for循环

(1)语法

    1)语法一:

    for 变量 in  值1 值2 值3

       do

           程序

       done

例:批量解压

#!/bin/sh

cd /tmp/baktar

ls *.tar.gz > ls.log

for i in $(cat ls.log)

do

    tar -zxf $i &>> /dev/null

done

rm -rf /tmp/baktar/ls.log

2)语法二:

    for (( 初始值;循环控制条件;变量变化 ))

       do

           程序

       done

例:从1加到100

#!/bin/sh

s=0

for (( i=1;i<=100;i++ ))

  do

    s=$(( $s + $i ))

  done

echo "the sum of:$s"

(2)案例

例1:批量添加用户:

#!/bin/sh

read -t 30 -p "please input username" name

read -t 30 -p "please user number" num

read -t 30 -s -p "please user password" pass

if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ]

  then

    y=$(echo $num | sed 's/^[0-9]*//g')

    if [ -z "$y" ]

    then

        for(( i=1;i<=$num;i++ ))

        do

          /usr/sbin/useradd ${name}${i} &> /dev/null

          echo $pass | /usr/bin/passwd --stdin ${name}${i} &> /dev/null

        done

    else

        echo "user number error"

    fi

fi

例2:计算0到100的和并输出计算过程:

#!/bin/sh

sum=0

for(( i=1;i<=100;i++ ))

do

 s=$sum

 sum=$(( $sum + $i ))

 echo "$s + $i = $sum"

done

3、循环的控制命令

(1)break n :跳出循环,n代表跳出循环的层数,如果省略标识跳出整个循环

(2)continue n :n表示退出第n层循环,如果省略n标识跳出本次循环,忽略本次循环的剩余代码,进入循环的下一次循环。

(3)exit n :退出当前shell程序,n为返回值,n也可以省略,在下一个程序里通过$?接受这个n值

(4)return n :用于在函数里,作为函数的返回值,用于判断函数是否执行正确。

4、while循环和until循环

(1)while循环

    1)while是不定循环,也称作条件循环,主要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环则会停止

    2)语法:

     while [ 条件判断式 ]

       do

           程序

       done

例1:计算1到100的和:

#!/bin/sh

i=1

s=0

while [ $i -le 100 ]

  do

        s=$(( $s + $i ))

        i=$(( $i + 1 ))

  done

echo "the sum is:$s"

例2:读取一个文件,一行一行打印该文件

#!/bin/bash

declare -i i=1

while read line;do

   echo  "Line is ${i}:$line"

   i=i+1

done < /etc/inittab

(2)until循环

    1)和while循环相反,until循环时只要条件判断式不成立则进行循环,一旦循环条件成立,则终止循环

    2)

    until [ 条件判断式 ]

    do

       程序

    done

例:计算1到100的和:

#!/bin/sh

i=1

s=0

until [ $i -gt 100 ]

  do

        s=$(( $s + $i ))

        i=$(( $i + 1 ))

  done

echo "the sum is:$s"                  

5、case语句

(1)语法:

    case $变量名 in

    值1)

       如果变量的值等于值1,则执行程序1

    ;;

    值2)

       如果变量的值等于值2,则执行程序2

    ;;

    ……

    *)

       如果变量的值都不是以上的值,则执行此程序

    ;;

    esac

(2)案例:

例1:简单的case判断

#!/bin/sh

read -t 30 -p "please choose yes/no:" cho

case $cho in

        "yes")

            echo "your choose is yes!"

        ;;

        "no")

            echo "you choose is no"

        ;;

        *)

            echo "your choose is error"

        ;;

esac

例2:用case打印水果菜单接受用户选择并输出

#!/bin/sh

RED_COLOR='\033[31m'

GREER_COLOR='\033[32m'

YELLOW_COLOR='\033[33m'

RES='\033[0m'

while true

do

  menu(){

  cat <<END

  1.apple

  2.pear

  3.banana

  4.exit

END

  }

menu

read -p "please input your cheoise:" fruit

case "$fruit" in

    1)

        echo -e "$RED_COLOR apple $RES"

    ;;

    2)

        echo -e "$GREER_COLOR pear $RES"

    ;;

    3)

        echo -e "$YELLOW_COLOR banana $RES"

    ;;

    4)

        exit 0

    ;;

    *)

        echo "no fruit you choose"

        exit 1

esac

done

6、案例

 例1、将尝试登陆系统10次失败的用户加入/etc/hosts.deny(脚本完成后使用nohup bah /scripts/ssh_deny.sh &)

#!/bin/bash

 

while true

do

lastb -n 100 | grep -v "btmp" |  grep -v "^$" | grep -v "172.16.252.100" | tr -s " " | cut

-d" " -f3 | sort | uniq -c | sort -nr > hacker.log

   while read line;do

       COUNT=`echo ${line} | awk '{print $1}'`

       IPADDR=`echo ${line} | awk '{print $2}'`

       if [[ ${COUNT} -gt 5 ]];then

          grep -q ${IPADDR} /etc/hosts.deny

          if [ ! $? -eq 0 ];then

                echo "sshd:${IPADDR}" >> /etc/hosts.deny

          fi

       fi

  done < hacker.log

done

2DOS攻击自动防护脚本(执行时需要放入后台如:sh whidos.sh &)

#!/bin/sh

while true

do

    awk '{print $1}' /var/log/httpd/access_log | grep -v "^$" | sort | uniq -c >/tmp/tmp.log

    exec </tmp/tmp.log

    while read line

    do

        ip=`echo $line | awk '{print $2}'`

        count=`echo $line | awk '{print $1}'`

        if [ $count -gt 20 ] && [ `iptables -L -n | grep "$ip" | wc -l` -lt 1 ]

          then

          iptables -I INPUT -s $ip -j DROP

          echo "$line is dropped" >>/tmp/drop/list.log

        fi

    done

    sleep 200

done

3:编写一个猜数字的游戏:要猜的数字为1 100 的随机整数,用户执行程序后根据提示输入一个数字,若输入的数字等于要猜的数字,提示成功,程序结束。若输入的数字不等于要猜的数字,提示大于或者小于要猜的数字,然后提示用户继续输入答案,直到用户猜出正确答案数字,程序终止

#!/bin/sh

AGE=`echo $[RANDOM%101]`

#echo $AGE

while true

do

read -p "please age,'q' or 'exit' to exit:" age

[ "$age" == "q" -o "$age" == "exit" ] && exit 0

#no1

[ -z "$age" ] && echo "please a number" && continue

#no2

expr $age + 0 &>/dev/null

ret=$?

[ $ret -ne 0 ] && echo "please input a integer" && continue

#no3

if [ $age -eq $AGE ]

    then

        echo "guess right.........."

        exit 0

    elif [ $age -lt $AGE ]

    then

        echo "cai xiao le"

    else

        echo "cai da le"

fi

done