Shell中的流程控制语句

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
例2:DOS攻击自动防护脚本(执行时需要放入后台如: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

猜你喜欢

转载自www.linuxidc.com/Linux/2017-04/142874.htm
今日推荐