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 條件測試 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 條件測試 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 對文件逐行處理 --> while
循環次數固定的ping主機探測
[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..."
[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..."
[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..."
[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}"
[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}"
[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}"