• 05Shell循环语句


    循环语句

    for

    语法结构

    for 变量名 [ in 取值列表 ]
    do
    循环体
    done 
    

    注意 当for对文件内容进行逐行处理时,会忽略空行

    示例

    例1

    ping 主机的脚本(初始版):缺点执行过程慢,Ctrl+C只能结束某一个循环,并不能结束脚本

    [root@hadoop04 shell_for]# vim ping.sh 
    #!/usr/bin/bash
    ##########################################
    # ping test                              #
    # v1.0 by ElegantSmile 9/12/2019         #
    ##########################################
    
    
    reset_col="e[0m"
    red_col="e[31m"
    green_col="e[32m"
    
    # 通过输出重定向,在ping之前清理ip_up.txt和ip_down.txt的内容
    >ip_up.txt
    >ip_down.txt
    
    # 产生序列有两种方式
    # {n..m}
    # `seq n m`
    # n<m
    for i in `seq 200`
    for i in `seq 200`
    do
            ip=172.22.34.${i}
            ping -c1 -W1 ${ip} &> /dev/null
            if [ $? -eq 0 ];then
                    echo -e "${green_col}${ip} is up${reset_col}" | tee -a ip_up.txt
            else
                    echo -e "${red_col}${ip} is down${reset_col}" | tee -a ip_down.txt
            fi
    done
    

    例2

    ping 主机的脚本(改进版):每一个循环放入一个子shell中执行,可以大大地加快脚本执行的速度

    注意 1.将循环放到后台运行 {}& 2.wait 3.执行脚本前清理文件内容

    [root@hadoop04 shell_for]# vim ping01.sh 
    #!/usr/bin/bash
    ##########################################
    # ping test                              #
    # v1.1 by ElegantSmile 9/12/2019         #
    ##########################################
    
    # 通过输出重定向,在ping之前清理ip_up.txt和ip_down.txt的内容
    >ip_up.txt
    >ip_down.txt
    
    reset_col="e[0m"
    red_col="e[31m"
    green_col="e[32m"
    
    
    for i in `seq 100 200`
    do
    		# 将循环放到后台进程执行
            {
            ip=172.22.34.${i}
            ping -c1 -W1 ${ip} &> /dev/null
            if [ $? -eq 0 ];then
                    echo -e "${green_col}${ip} is up${reset_col}" | tee -a ip_up.txt
            else
                    echo -e "${red_col}${ip} is down${reset_col}" | tee -a ip_down.txt
            fi
            }&
    done
    
    #等待前面的所有后台进程结束
    wait
    
    echo "finish..."
    

    两个版本的脚本执行时间比较

    改进版

    [root@hadoop04 shell_for]# time bash ping01.sh 
    (略)
    finish...
    
    real	0m1.208s
    user	0m0.338s
    sys	0m0.781s
    

    初始版

    [root@hadoop04 shell_for]# time bash ping.sh 
    (略)
    
    real	2m16.459s
    user	0m0.277s
    sys	0m0.677s
    

    例3

    ping 指定主机

    # 指定主机的IP地址
    [root@hadoop04 shell_for]# vim ip.txt
    172.22.34.18
    172.22.34.89
    172.22.34.56
    172.22.34.192
    172.22.34.94
    172.22.34.243
    
    # 编写脚本
    [root@hadoop04 shell_for]# vim ping02.sh
    #!/usr/bin/bash
    ##########################################
    # ping test                              #
    # v1.2 by ElegantSmile 9/12/2019         #
    ##########################################
    
    ip_txt=$1
    
    reset_col="e[0m"
    red_col="e[31m"
    green_col="e[32m"
    
    
    for ip in `cat ${ip_txt}`
    do
            {
            ping -c1 ${ip} &> /dev/null
            if [ $? -eq 0 ];then
                    echo -e "${green_col}${ip} is up${reset_col}"
            else
                    echo -e "${red_col}${ip} is down${reset_col}"
            fi
            }&
    done
    
    wait
    
    echo "finish..."
    
    # 执行脚本
    [root@hadoop04 shell_for]# time bash ping02.sh ip.txt 
    172.22.34.18 is up
    172.22.34.56 is down
    172.22.34.192 is down
    172.22.34.94 is down
    172.22.34.243 is down
    172.22.34.89 is down
    finish...
    
    real	0m3.018s
    user	0m0.008s
    sys	0m0.017s
    

    例4

    创建用户,输入前缀、密码、数量;确认输入的信息;根据用户存在与否,提示已经存在或者创建用户

    [root@hadoop04 shell_for]# vim create_user01.sh
    !/usr/bin/bash
    ##########################################
    # add user                               #
    # v1.0 by ElegantSmile 9/12/2019         #
    ##########################################
    
    
    while :
    do
            read -p "Please enter prefix & password & num[tianyun 123 5]" prefix pass num
    
            printf "user information:
            --------------------------
            user prefix: ${prefix}
            user password: ${pass}
            user number: ${num}
            --------------------------
            "
    
            read -p "Are you sure?[y|n]: " action
    
            if [ "${action}" = "y" ];then
                    break
            fi
    done
    
    # seq -w 等位补齐
    for i in `seq -w ${num}`
    do
            username=${prefix}${i}
            id ${username} &> /dev/null
            if [ $? -eq 0 ];then
                    echo "user ${username} already exists"
            else
                    useradd ${username}
                    echo "${pass}" | passwd --stdin ${username} &> /dev/null
                    if [ $? -eq 0 ];then
                            echo "user ${username} is created"
                    fi
            fi
    done
    

    例5

    创建用户,通过文件指定要创建的用户和密码

    # 编辑用户信息文件user.txt
    [root@hadoop04 shell_for]# vim user.txt 
    alice  123123
    jeve   7dsgf9
    
    # 编写脚本
    [root@hadoop04 shell_for]# vim create_user02.sh
    #!/usr/bin/bash
    ##########################################
    # add user                               #
    # v1.1 by ElegantSmile 10/12/2019        #
    ##########################################
    
    
    # 执行脚本时,必须传入一个参数
    if [ $# -eq 0 ];then
            echo "usage: `basename $0` file"
            exit 1
    fi
    
    # 执行脚本时,必须传入一个参数
    if [ $# -eq 0 ];then
            echo "usage: `basename $0` file"
            exit 1
    fi
    
    # 执行脚本时,传入的参数必须是文件
    if [ ! -f $1 ];then
            echo "error file"
            exit 2
    fi
    
    # 定义变量
    user_text=$1
    
    #IFS 内部字段分隔符
     IFS=$'
    '
    
    for line in `cat "${user_text}"`
    do
            # 获取指定用户的用户名和密码
            username=`echo "${line}" | awk '{print $1}'`
            userpass=`echo "${line}" | awk '{print $2}'`
            id ${username} &> /dev/null
            if [ $? -eq 0 ];then
                    echo "user ${username} already exists"
                    continue
            fi
            useradd ${username} &> /dev/null && echo "${userpass}" | passwd --stdin ${username} &> /dev/null
            if [ $? -eq 0 ];then
                    echo "user ${username} is created"
                    echo "userpassword: ${userpass}"
            fi
    done
    

    例6

    批量修改主机密码

    while

    语法结构

    while 条件测试
    do
    循环体
    done
    ==当条件测试成立(条件测试为`真`),执行循环体  
    

    注意

    ☆☆☆当需要对文件内容进行逐行处理时,推荐使用:

    while read line
    
    do
    
    循环体
    
    done < FILE
    

    示例

    例1

    创建用户,通过用户列表文件创建用户

    # 编辑用户信息文件user.txt
    [root@hadoop04 shell_while]# vim user.txt 
    alice  123123
    jeve   7dsgf9
    
    # 编写脚本
    [root@hadoop04 shell_while]# vim create_user01.sh
    
    #!/usr/bin/bash
    ##########################################
    # add user                               #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    while read userinfo
    do
            if [ ${#userinfo} -eq 0 ] ;then
                    echo "Nothing to do"
                    continue
            fi
            username=`echo "${userinfo}" | awk '{print $1}'`
            userpass=`echo "${userinfo}" | awk '{print $2}'`
            id "${username}" &> /dev/null
            if [ $? -eq 0 ];then
                    echo "user ${username} already exists"        else    
                    useradd ${username} &> /dev/null && echo "${userpass}" | passwd --stdin ${username} &> /dev/null
                    if [ $? -eq 0 ];then
                            echo "user ${username} is created"
                            echo "userpassword: ${userpass}"
                            echo "username: ${username}"
                    fi      
            fi
    
    done < user.txt
    
    echo "all ok..."
    

    until

    语法结构

    until 条件测试
    do
    循环体
    done
    ==当条件测试成立(条件测试为`假`),执行循环体  
    

    示例

    ping主机,检查IP状态

    # while循环
    # ip ping不通时提示
    # 类似于下线提示
    [root@hadoop04 shell_until]# vim ping01.sh 
    #!/usr/bin/bash
    ##########################################
    # ping hosts                             #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    ip=$1
    
    while ping -c1 -W1 ${ip}&> /dev/null:
    do
            sleep 1
    done
    
    echo "${ip} is down"
    
    
    # until循环
    # ip ping得通时提示
    # 类似于上线提示
    [root@hadoop04 shell_until]# vim ping02.sh 
    #!/usr/bin/bash
    ##########################################
    # ping hosts                             #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    ip=$1
    
    until ping -c1 -W1 ${ip}&> /dev/null:
    do
            sleep 1
    done
    
    echo "${ip} is up"
    

    For While Until对比

    循环次数固定的  --> for
    
    循环次数不固定的  --> while until
    
    对文件逐行处理  --> while
    

    ping主机探测

    循环次数固定的ping主机探测

    For

    [root@hadoop04 shell_for_while_until]# vim for_while_until_ping.sh 
    #!/usr/bin/bash
    ##########################################
    # ping hosts                             #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    for i in {2..254}
    do
    	{
    	ip=172.22.145.${i}
    	ping -c1 -W1 ${ip} &> /dev/null
    	if [ $? -eq 0 ];then
    		echo "${ip} is up"	
    	fi
    	} &
    done
    
    wait
    
    echo "all finish..."
    

    While

    [root@hadoop04 shell_for_while_until]# vim while_until_for_ping.sh 
    #!/usr/bin/bash
    ##########################################
    # ping hosts                             #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    i=2
    
    while [ $i -le 254 ]
    do
    	{
    	ip=172.22.145.${i}
    	ping -c1 -W1 ${ip} &> /dev/null
    	if [ $? -eq 0 ];then
    		echo "${ip} is up"	
    	fi
    	} &
    	let i++
    done
    
    wait
    
    echo "all finish..."
    

    Until

    [root@hadoop04 shell_for_while_until]# vim until_for_while_ping.sh 
    #!/usr/bin/bash
    ##########################################
    # ping hosts                             #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    i=2
    
    until [ $i -gt 254 ]
    do
    	{
    	ip=172.22.145.${i}
    	ping -c1 -W1 ${ip} &> /dev/null
    	if [ $? -eq 0 ];then
    		echo "${ip} is up"	
    	fi
    	} &
    	let i++
    done
    
    wait
    
    echo "all finish..."
    

    计算1-100的和

    For

    [root@hadoop04 shell_for_while_until]# vim for_while_until_sum100.sh
    #!/usr/bin/bash
    ##########################################
    # sum 100                                #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    
    for i in {1..100}
    do
            #let sum=${sum}+${i}
            let sum+=${i}
    done
    
    echo "sum: ${sum}"
    

    While

    [root@hadoop04 shell_for_while_until]# vim while_until_for_sum100.sh
    #!/usr/bin/bash
    ##########################################
    # sum 100                                #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    i=1
    
    while [ ${i} -le 100 ]
    do
            #let sum=${sum}+${i}
            let sum+=${i}
            let i++
    done
    
    echo "sum: ${sum}"
    

    Until

    [root@hadoop04 shell_for_while_until]# vim until_for_while_sum100.sh
    #!/usr/bin/bash
    ##########################################
    # sum 100                                #
    # v1.0 by ElegantSmile 10/12/2019        #
    ##########################################
    
    i=1
    
    until [ ${i} -gt 100 ]
    do
            #let sum=${sum}+${i}
            let sum+=${i}
            let i++
    done
    
    echo "sum: ${sum}"
    
  • 相关阅读:
    Rancher安装
    JDK8日期时间对象
    String经典面试题
    String
    单例模式
    多线程
    接口
    代码块
    内存吞金兽(Elasticsearch)的那些事儿 -- 常见问题痛点及解决方案
    内存吞金兽(Elasticsearch)的那些事儿 -- 写入&检索原理
  • 原文地址:https://www.cnblogs.com/ElegantSmile/p/12056477.html
Copyright © 2020-2023  润新知