天天看點

流程控制之for循環、select語句for循環流程控制之select語句

for循環

一、文法

#Shell風格文法
for 變量名 [ in 取值清單 ]
do
	循環體
done

#C語言風格文法
for ((初值;條件;步長))
do	
	循環體
done
           

shell風格的for,常用in清單方式

for i in 1 2 3
for i in {1,2,3}
for i in {1..9}
for i in {9..1}
for i in {a..z}
for i in {A..Z}
for i in {X..Z}
for i in $(指令)  # 例如:for i in $(head -10 /etc/passwd);do echo $i|cut -d: -f1,2;done
for i in $(find ...)
           

continue與break

continue:預設退出本次循環
break:預設退出本層循環
           

二 案例

案例1:shell風格的for

for i in {1..10}
do
    echo $i
done
           

案例2:c語言風格的for

for ((i=1;i<=10;i++))
do
    echo $i
done
           

案例3:檢查内網存活的ip,使用&符号提升腳本的運作效率

#!/bin/bash
for i in {1..254}
do
    (ping -W 1 -c 1 192.168.12.$i &> /dev/null && echo 192.168.12.$i) &
done
           

拓展:ping指令參數

指令參數:

-d 使用Socket的SO_DEBUG功能。

-f  極限檢測。大量且快速地送網絡封包給一台機器,看它的回應。

-n 隻輸出數值。

-q 不顯示任何傳送封包的資訊,隻顯示最後的結果。

-r 忽略普通的Routing Table,直接将資料包送到遠端主機上。通常是檢視本機的網絡接口是否有問題。

-R 記錄路由過程。

-v 詳細顯示指令的執行過程。

<p>-c 數目:在發送指定數目的包後停止。

-i 秒數:設定間隔幾秒送一個網絡封包給一台機器,預設值是一秒送一次。

-I 網絡界面:使用指定的網絡界面送出資料包。

-l 前置載入:設定在送出要求資訊之前,先行發出的資料包。

-p 範本樣式:設定填滿資料包的範本樣式。

-s 位元組數:指定發送的資料位元組數,預設值是56,加上8位元組的ICMP頭,一共是64ICMP資料位元組。

-t 存活數值:設定存活數值TTL的大小。(探測時間)
           

案例4:編寫檔案類型測試腳本,支援多個參數

[[email protected] ~]# vim file.sh 
#!/bin/bash
for i in $@
do
        if [[ -d $i ]];then
        echo "$i is directory."
        elif [[ -b $i  ]];then
        echo "$i is block device."
    elif [[ -f $i ]];then
        echo "$i is a regular file."
    else
        echo "unknow."
    fi
done
[[email protected] ~]# chmod +x file.sh 
[[email protected] ~]# ./file.sh a.txt /etc /root /abc
unknow.
/etc is directory.
/root is directory.
unknow.
           

案例5:可以直接在指令行編寫for循環

#continue,跳過本次循環

#break結束循環

[[email protected] ~]# for i in {1..10};do [ $i -eq 5 ] && continue || echo $i;done
[[email protected] ~]# for i in {1..10};do [ $i -eq 5 ] && break || echo $i;done
           

案例6:統計dev下每種檔案類型的數量

[[email protected] ~]# vim file.sh
#!/bin/bash
dir='/dev'
for i in `ls $dir`
do
    if [ -b $dir/$i ];then
        ((block++))  # 或者 let block++,下同
    elif [ -f $dir/$i ];then
        ((file++))
         
    elif [ -d $dir/$i ];then
        ((directory++))
    else
        ((unkown++))
    fi
done

echo 'block' $block
echo 'regular file' $file
echo 'directory' $directory
echo 'unkown' $unkown

[[email protected] ~]# sh file.sh 
block 6
regular file 1
directory 18
unkown 127
           

案例7:向腳本傳遞一個使用者名,驗證這個使用者是否存在.

[[email protected] ~]# cat testuser.sh
#!/bin/bash
id $1 &> /dev/null
if [ $? -eq 0 ];then
    echo "使用者$1存在"
else
    echo "使用者$1不存在"
fi
[[email protected] ~]# sh testuser.sh nginx
使用者nginx存在
           

案例8:添加30個使用者,再将它們删除

[[email protected] ~]# vim user.sh
for i in {1..30};
do
    useradd user$i&&echo "user$i create successful"
done

for i in {1..30};
do
    userdel -r user$i&&echo "user$i delete successful"
done
           

案例9:輸入賬号資訊,輸入個數,批量建立使用者user01、user02、user03…,密碼預設123456

[[email protected] ~]# cat adduser.sh 
#!/bin/bash
read -p "請輸入建立的使用者名資訊: " name
read -p "請輸入建立的使用者數量: " count

for i in `seq -w $count`
do
    echo $name$i
    useradd $name$i &>/dev/null
    echo 123456 | passwd --stdin $name$i &>/dev/null
    id $name$i &>/dev/null
    [ $? -eq 0 ] && echo "$name$i create is ok" || echo "$name$i create is failed"
done
           

案例10:嵌套多層for循環,結合break與continue,(了解即可)

#1、使用break:
break 預設參數是 1 
是以寫 break 等于 break 1
意義:退出目前循環層
break 2 則向上退出2層循環 目前循環也計算在退出層次裡

# 示例
for i in {0..3}
do
    echo -e "第一層循環:loop$i"
    for j in {0..3} 
    do
        echo -e "\t第二層循環:loop$j"
        for n in {0..3}
        do
            echo -e "\t\t第三層循環:loop$n:$i$j$n"
            if ((n==2));then
                break 3
            fi
        done
    done
done
案例11:for循環實作九九乘法表
[[email protected] ~]# cat for1.sh 
for i in {1..9}
do
    for (( j=1;j<=i;j++ ))
    do 
       let "res=$i*$j"
       echo -n "$i*$j=$res" 
       echo -n "   " 
    done
    echo ""
done


[[email protected] ~]# sh test.sh 
第一層循環:loop0
	第二層循環:loop0
		第三層循環:loop0:000
		第三層循環:loop1:001
		第三層循環:loop2:002

#2、使用continue
continue = continue 1
在當次循環中忽略continue後續的代碼
就是:立即結束目前循環中的當次循環,而轉入目前循環的下一次循環

continue 2 等同于 break 1
continue 3 等同于 break 2
總結:continue n 等同于 break n-1

for i in {0..3}
do
    echo -e "第一層循環:loop$i"
    for j in {0..3} 
    do
        echo -e "\t第二層循環:loop$j"
        for n in {0..3}
        do
            echo -e "\t\t第三層循環:loop$n:$i$j$n"
            if ((n==2));then
                continue 3
            fi
        done
    done
done

[[email protected] ~]# sh test.sh 
第一層循環:loop0
	第二層循環:loop0
		第三層循環:loop0:000
		第三層循環:loop1:001
		第三層循環:loop2:002
[[email protected] ~]# vim test.sh
[[email protected] ~]# sh test.sh 
第一層循環:loop0
	第二層循環:loop0
		第三層循環:loop0:000
		第三層循環:loop1:001
		第三層循環:loop2:002
第一層循環:loop1
	第二層循環:loop0
		第三層循環:loop0:100
		第三層循環:loop1:101
		第三層循環:loop2:102
第一層循環:loop2
	第二層循環:loop0
		第三層循環:loop0:200
		第三層循環:loop1:201
		第三層循環:loop2:202
第一層循環:loop3
	第二層循環:loop0
		第三層循環:loop0:300
		第三層循環:loop1:301
		第三層循環:loop2:302
           

流程控制之select語句

一、文法

select表達式是bash的一種擴充應用,擅長于互動式場合。使用者可以從一組不同的值中進行選擇

select var in ...
do
	...
	break
done
           

二、案例

案例1:

[[email protected] ~]# vim select.sh
#!/bin/bash
PS3='choose one: ' # select預設使用PS3變量的值做提示符
echo
select var in {A..D}
do
    echo
    echo "your choose is $var"
    echo "OK"
    echo
    break # 跳出select,否則是死循環
done

[[email protected] ~]# sh select.sh 
1) A
2) B
3) C
4) D
choose one: 3

your choose is C
OK
           

案例二:

[[email protected] ~]# cat select.sh 
#!/bin/bash
PS3='選一個吧,小老弟: ' # select預設使用PS3變量的值做提示符
echo

select var
do
    echo
    echo "your choose is $var"
    echo "OK"
    echo
    break # 跳出select,否則是死循環
done

[[email protected] ~]# sh select.sh 蘋果 梨 蔬菜 香蕉 茄子

1) 蘋果
2) 梨
3) 蔬菜
4) 香蕉
5) 茄子
選一個吧,小老弟: 1

your choose is 蘋果
OK