05Shell循環語句

循環語句

for

語法結構

for 變量名 [ in 取值列表 ]
do
循環體
done

注意 當for對文件內容進行逐行處理時,會忽略空行shell

示例

例1vim

ping 主機的腳本(初始版):缺點執行過程慢,Ctrl+C只能結束某一個循環,並不能結束腳本bash

[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

例2oop

ping 主機的腳本(改進版):每個循環放入一個子shell中執行,能夠大大地加快腳本執行的速度測試

注意 1.將循環放到後臺運行 {}& 2.wait 3.執行腳本前清理文件內容code

[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..."

兩個版本的腳本執行時間比較orm

改進版進程

[root@hadoop04 shell_for]# time bash ping01.sh 
(略)
finish...

real    0m1.208s
user    0m0.338s
sys 0m0.781s

初始版ip

[root@hadoop04 shell_for]# time bash ping.sh 
(略)

real    2m16.459s
user    0m0.277s
sys 0m0.677s

例3hadoop

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=$'\n'

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}"
相關文章
相關標籤/搜索