Shell版本循环语句(if//for/while/case)

if选择结构

if单分支处理:当“条件成立”时执行命令序列xx,否则,不执行任何操作(只判断为真

    if [条件测试] ; then

      命令序列xx

fi

 

示例:检测/media/cdrom目录,若不存在则创建 

   #!/bin/bash

    MOUNT_DIR="/media/cdrom/"

    if [ ! -d $MOUNT_DIR ] ;  then

        mkdir -p $MOUNT_DIR

    fi 

示例:每分钟判断当前登陆用户是否超过3人,若超过3人,自动发送邮件给root,报警!

#!/bin/bash

num=$(who |wc -l)    #计算登陆用户

if [ $num -gt 3 ];then    #判断用户是否大于3,如果大于,则发送邮件

        mail -s Warning [email protected] < /root/mail.txt

    mail -s Warning root < /root/mail.txt

fi

1、chmod +x test.sh

2、将脚本放到计划任务内:crontab -e

* * * * * /root/test.sh

示例:如果是管理员,执行所有命令

#!/bin/bash

if [ $USER == root ];then

yum -y install vsftpd

systemctl start vsftpd

systemctl enable vsftpd`

fi

###############################################################################

if 双分支处理:当“条件成立”时执行命令序列xx,否则,执行命令序列yy(非对即错

if [条件测试] ; then

    命令序列xx

else

    命令序列yy

fi

 

 

示例:检测并判断指定的主机是否可ping通。用户输入IP地址,判断是否能ping通。能则输出ip地址up;不能则输出ip地址down。

为了节省ping测试时间,可以只发送3个测试包(-c 3)、缩短发送测试包的间隔秒数(-i 0.2)、等待反馈的超时秒数(-W 3)。

#!/bin/bash

read -p '请输入您要测试的IP地址:' ip

ping  -c 2 -i 0.1 -W 2 $ip &> /dev/null

if [ $? -eq 0 ] ; then

echo "Host $ip is up."

else

echo "Host $ip is down."

fi

# chmod +x pinghost.sh

# ./pinghost.sh 192.168.4.5

示例:判断用户输入的用户名,该用户是否存在,存在则输出用户id基本信息,不存在则创建此用户

#!/bin/bash

read -p '请输入您的用户名:' user

id $user &> /dev/null         或使用useradd $user 

if [ $? -eq 0 ];then

   echo 用户已经创建

else

   echo 用户已存在

   id $user

fi

 


if 多分支处理:当条件1满足时,作xx处理;否则继续检查

条件2,若成立则作yy处理;否则,作zz处理

相当于多层if语句嵌套,针对多个条件分别执行不同的操作

if [条件测试1] ; then

    命令序列xx

elif 条件测试2 ; then

命令序列yy

      .. ..

else 

      命令序列zz

fi

 

脚本的退出状态:取决于退出前最后一条命令的 $? 值,或者“exit 整数值”指定。

示例:猜数字游戏:

#!/bin/bash

num=$[RANDOM%100]

for i in {1..10}               

do

read -p "请输入一个范围在「0-99」的数字:  "  guess

if [ $num -eq $guess  ];then

echo "你猜对了,恭喜您!!!"

echo "随机数为:$num;         您猜的数字为:$guess"

echo "恭喜,猜对了,猜了$i次"

exit

elif [ $num -lt $guess ];then

echo "您猜错了,您输入的数字比随机数大,您猜了$i次"

echo "您猜的数字为:$guess"

else

echo "您猜错了,您输入的数字比随机数小,您猜了$i次"

echo "您猜的数字为:$guess"

fi

done

示例:从键盘读取一个论坛积分,判断论坛用户等级

大于等于90 神功绝世

大于等于80,小于90 登峰造极

大于等于70,小于80 炉火纯青

大于等于60,小于70 略有小成

大于60 初学乍练   

 #!/bin/bash

    read -p "请输入积分(0-100):" JF

    if [ $JF –ge 90 ] ; then

        echo "$JF 分,神功绝世"

    elif [ $JF –ge 80 ] ; then

        echo "$JF 分,登峰造极"

    elif [ $JF –ge 70 ] ; then

        echo "$JF 分,炉火纯青"

    elif [ $JF –ge 60 ] ; then

        echo "$JF 分,略有小成"

    else

        echo "$JF 分,初学乍练"

    fi

# chmod +x gradediv.sh

# ./gradediv.sh 

示例:输入一个分数,判断成绩分档:85-100优秀、70-84良好、低于70分不合格

#!/bin/bash

read  -p  '请输入您的分数(0-100):'  FS

if [ $FS -ge 85 ] && [ $FS -le 100 ];then

  echo “ $FS分!优秀 ”

elif [ $FS -ge 70 ] && [ $FS -le 84 ];then

  echo “ $FS分!合格 ”

else

  echo “ $FS分!不合格 ”

fi

示例:当运行/root/foo.sh redhat,输出为fedora;当运行/root/foo.sh fedora,输出为redhat;当没有任何参数或者参数不是 redhat 或者 fedora时,其错误输出产生以下信息: /root/foo.sh redhat|fedora

1)编写脚本代码# vim  /root/foo.sh   

 #!/bin/bash

    if [ "$1" == "redhat" ]  

    then

           echo "fedora"

    elif [ "$1" == "fedora" ] 

    then

           echo "redhat"

    else

           echo "/root/foo.sh redhat|fedora" >&2

fi

另一种写法:

if [ $# == 0 ];then

echo '/root/foo.sh redhat |fedora' >&2    #为了对错误输出进行收集,可通过2>file查看

elif [ $1 == redhat ];then

     echo fedora

elif [ $1 == fedora ];then

     echo redhat

else 

     echo '/root/foo.sh redhat |fedora' >&2

fi

2)添加x执行权限# chmod  +x  /root/foo.sh 

3) 测试提供正确参数的情况  # /root/foo.sh  redhat  

测试提供非预期参数的情况# /root/foo.sh  ubuntu

    测试不提供参数的情况 # /root/foo.sh

###############################################################################

列表式循环——给定一批对象,反复执行类似的操作(如购票者==>售票)

for循环处理

遍历/列表式循环:根据变量的不同取值,重复执行xx处理

列表式for循环结构:

    for  变量名  in  值1  值2  值3 .. .. (变量名一般习惯用i)

    do

            命令序列($变量名)

    done

 

示例:造数1:touch {1..10000}.txt  

#!/bin/bash

for i in `seq 10000`

do 

touch /tmp/$i.txt

done

示例:造数2:touch {01..10}.txt

#!/bin/bash

for i in {1..10} 

do 

  useradd stu$i 

  echo 123456 | passwd --stdin stu$i &> /dev/null

  echo stu$i创建成功

   id  test$a

done

示例:编写一个批量添加用户脚本,此脚本要求提供用户名列表文件作为参数,列表测试文件:http://classroom/pub/materials/userlist。如果没有提供参数,此脚本应该给出提示 Usage: /root/batchusers,退出并返回相应值;如果提供一个不存在的文件,此脚本应该给出提示 Input file not found,退出并返回相应值

1)编写脚本代码# vim  /root/batchusers   

 #!/bin/bash

    if [ $# -eq 0 ] ; then  #判断位置变量为0个

        echo ‘Usage: /root/batchusers’ >&2    #将正确信息变成错误信息

        exit 1                                  #退出返回值为1

    fi

    if [ ! -f $1 ] ; then    #文本不存在为真

        echo ‘Input file not found’ >&2      #将正确信息变成错误信息

        exit 2                                  #退出返回值为2

    fi

    for name in $(cat $1)    #  $1为文件,cat $1可以显示为文本参数,$()传递参数

    do

        useradd  -s  /bin/false  $name

    done

2)添加x执行权限# chmod  +x  /root/batchusers 

3)测试batchusers批量添加用户脚本

下载用户列表测试文件: 

# wget  http://classroom/pub/materials/userlist -O  /root/userlist            

 # cat  /root/userlist          //检查下载文件

实现批量添加用户:# /root/batchusers  /root/userlist      

 # id  duanwu

测试其他异常处理: 

# /root/batchusers   //未提供列表文件, Usage: /root/batchusers           # echo  $?      //返回1     

# /root/batchusers  /root/userlist.txt   //提供的列表文件找不到,Input file not found       

# echo  $?       //返回2

###############################################################################

作业:

根据输入成绩的分数 输出不同的提示信息

把指定的文件备份到指定的目录下

判断用户从键盘输入的数据是偶数还是奇数?

计算用户输入1-10之间的任意一个数的平方值,不输入数字的时候给出错误提示信息。

###############################################################################

循环结构

在Shell脚本应用中,常见的for循环采用遍历式、列表式的执行流程,通过指定变量从值列表中循环赋值,每次复制后执行固定的一组操作。

for循环的语法(格式1)

for 变量名 in 值列表

do

命令序列

done

 

示例:批量添加用户帐号(名称没有规律)

素材:/root/users.txt

#!/bin/bash

ULIST=$(cat /root/users.txt)

for UNAME in $ULIST

do

useradd $UNAME  2>/var/err/log

echo "123456" | passwd --stdin $UNAME > /dev/null

done

# chmod +x uaddfor.sh 

# ./uaddfor.sh

示例:使用循环ping测试网络中所有主机

#!/bin/bash

net=192.168.4.

for i in `seq 1 254`  #反引号     //{1..254}

do

ping -c 3 -i 0.2 -w 0.2 $net$i &>/dev/null

if [ $? -eq 0 ];then

     echo "该主机$net$i,ping通"

else

echo "该主机$net$i,无法ping通"

fi

done

C语言风格的for循环(格式2)

通过变量控制,条件成立时循环;步长可控次数

for ((初值;条件;步长控制))

do

命令序列

done

#!/bin/bash

for ((i=1;i<=5;i+=2))         //或for ((i=1;i<=5;i++))

do

echo $i

done

示例:制作9*9乘法表

#!/bin/bash

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

do

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

     do

        echo -n "$i*$j=$((i*j))"

     done

 echo

done

++++++++++++++++++++++++

字体色:echo -e "\033[34mOK\033[0m"

背景色:echo -e "\033[44mOK\033[0m"

 

for  第一个人  in  张三  李四  王五  .. ..

do

为第一个人采血

done

 

for  第一个人  in  $(cat  用户列表文件)

do

为第一个人采血

done

 

for  第一个人  in  $(cat  $1)

do

为第一个人采血

done

 

for  NAME  in  $(cat  $1)

do

useradd   -s  /bin/false  $NAME

done


while循环格式

——条件式循环:反复测试条件,只要成立就执行命令序列

while循环属于条件式的执行流程,会反复判断指定的测试条件,只要条件成立即执行固定的一组操作,直到条件变化为不成立为止。所以while循环的条件一般通过变量来进行控制,在循环体内对变量值做相应改变,以便在适当的时候退出,避免陷入死循环。

while 条件测试

do

    命令序列

done

 

for循环的循环次数根据值列表而固定,而while循环的循环次数不固定

+++++++++++++++++++++++++++++++++

示例:批量添加用户(名称有规律)

#!/bin/bash

PREFIX=”stu”; i=1                         #定义用户名前缀

while [ $i -le 20 ]
do
    useradd ${PREFIX}$i               #添加的用户名为:前缀+编号           
echo “123456” | passwd --stdin ${PREFIX}$i &> /dev/null
let i++      #递增控制,避免死循环
done

# chmod +x uaddwhile.sh 

# ./uaddwhile.sh

# grep ^stu /etc/passwd              #检查添加的用户

批量删除用户账号udelwhile.sh

将上一示例的命令改为

    userdel -r ${PREFIX}$i &> /dev/null

    let i++

# grep ^stu /etc/passwd                  //再检查已无相应账号信息

示例:检测192.168.4.0/24网段,列出不在线的主机地址

#!/bin/bash

NET="192.168.4."   ; i=1

while [ $i -le 254 ]
do
    IP="${NET}$i"
    ping -c 3 -i 0.2 -W 1 $IP &> /dev/null
    if [ $? -eq 0 ] ; then
        echo "Host $IP is up."
    else
        echo "Host $IP is down."
    fi
    let i++
done

示例:猜数字

#!/bin/bash
#这是一个猜数字的游戏

biggest=10        #(代表取数据的最大值)
guess=0           #(玩家输入的数字)
guesses=0         #(输入数字的次数)

number=$(($$ % $biggest))   #random number, between 1 and $biggest,$$代表当前脚本执行的PID,可以当作以一个随机数

while [ $guess -ne $number ]
do 
echo -n "Guess?" ; read guess

if [ $guess -lt $number ];then
echo "...猜小了!"
elif [ $guess -gt $number ];then
echo "...猜大了!"
fi

guesses=$(($guesses + 1))
done

echo "猜对了!!!Guessed $number in $guesses guesses."
exit 0

#echo -n 回避换行
#guess=0,定义一个变量,这里存在bug,如果guess取值为0,会出错

+++++++++++++++++++++++++++++

死循环

while :                  while True

do                               do

    命令                             命令

done                              done

+++++++++++++++++++++++++++++

示例:猜数字

#!/bin/bash

num=$[RANDOM%100+1]  ;i=0

while :
do
read -p "请输入一个数字,范围为[1-100]:" guess
let i++
if [ $guess -eq $num ];then
        echo “蒙对了,猜了$i次”
        exit
elif [ $guess -gt $num ];then
        echo “蒙大了”
else
        echo “蒙小了”
fi
done

示例:点名器,屏幕随机刷人名(1-n行数)

#!/bin/bash

user=/root/users.txt

while :
do
    clear
    line=`cat $user |wc -l`
    num=$[RANDOM%$line+1]
    head -$num $user |tail -1
    sleep 0.2     #加上sleep 0.2 ,这样会使cpu的使用不致过高
done

示例:写个脚本,屏幕提示如下

1.查看IP;2.查看内存;3.查看CPU信息;4.查看硬盘;5.退出

请输入您的选项[1-5]: abc

#!/bin/bash

while :
do 

    clear

    echo -e "\033[34m    菜单\033[0m"
    echo "1.查看IP
          2.查看CPU
          3.查看磁盘
          4.查看内存
          5.退出"

read -p "请输入选项[1-5]:" i

if [ $i -eq 1 ];then
    ifconfig eth0 |grep "inet"
    read -p "按回车键继续..."
elif [ $i -eq 2 ];then
    cat /proc/cpuinfo |grep vendor
    cat /proc/cpuinfo |grep MH
    cat /proc/cpuinfo |grep cache
    read -p "按回车键继续..."
elif [ $i -eq 3 ];then
    df -h
    read -p "按回车键继续..."
elif [ $i -eq 4 ];then
    free
    read -p "按回车键继续..."
elif [ $i -eq 5 ];then
    exit
else
    read -p "请输入选项[1-5]:" i
fi

done

 


case语句(简化版if)

——检查变量的实际取值相匹配,则执行对应的操作

case分支属于匹配执行的方式,它针对指定的变量预先设置一个可能的取值,判断该变量的实际取值是否与预设的某一个值相匹配,如果匹配上了,就执行相应的一组操作,如果没有任何值能够匹配,就执行预先设置的默认操作。

case 变量值  in

模式1)

   命令序列1 ;;

模式2)

   命令序列2 ;;

*)

   默认命令序列

esac

 

示例:当用户输入参数redhat(fefora),则返回fefora(redaht),其他则提示用法

#!/bin/bash

if [ $1 ==  "redhat" ];then       # $1为脚本执行时的第一个参数
    echo "fedora"
elif [ $1 == "fedora" ];then
    echo "redhat"
else
    echo "用法: $0 {redhat|fedora}"
fi

或者

#!/bin/bash

case $1 in
redhat)
    echo "fedora";;
fedora)
    echo "redhat";;
*)      #默认输出脚本用法
    echo "用法: $0 {redhat|fedora}"
esac

示例:判断用户输入的是数字、字母、标点符号(击键类型)

#!/bin/bash

read -p "输入字符:" key

case $key in
[0-9])
    echo 数字;;
[a-Z])
    echo "字母";;
*)
    echo "空格、功能键或其他控制字符"
esac

++++++++++++++++++++++++++++

编写Apache启动脚本:

#yum -y install httpd

#vim test.sh

#!/bin/bash

#给Apache启动脚本添加开机启动功能
#chkconfig: - 88 90
#chkconfig --add myhttpd
#chkconfig --list myhttpd
#chkconfig myhttpd on
#chkconfig myhttpd off

case $1 in
start)
    /usr/sbin/httpd
    echo "我已经启动了";;
stop)
    kill `cat /var/run/httpd/httpd.pid`;;   #反引号
restart)
    kill `cat /var/run/httpd/httpd.pid`
        sleep 1
    /usr/sbin/httpd;;
status)
    if [ -f /var/run/httpd/httpd.pid ];then
        echo "httpd is 在运行..."
    else
        echo "没有running"
    fi;;
*)
    echo "用法是$0 {start|stop|restart|status}"
esac

 

你可能感兴趣的:(Linux命令,脚本)