1、for循環結構語法及實例
1.1、for循環結構語法1
for 變量名 in 變量取值列表
do
指令……….
done
提示:此結構中“in 變量取值列表”可省略,省略時相當於in “$@”,使用for i就相當於使用for i in “$@”
1.2、for循環結構語法2
for ((exp1;exp2;exp3)); do
指令…………
done
exp1只執行一次,相當於在for裏嵌了while
1.3、for循環結構基礎實例
例1:for循環直接輸出元素5到1的方法
#!/bin/bash
for num in 5 4 3 2 1
do
echo $num
done
例2:for循環使用大括號的方法輸出元素5到1
#!/bin/bash
for num in {5..1}
do
echo $num
done
例3:for循環使用seq方法實現輸出元素5到1
#!/bin/bash
for num in `seq -s " " 5 -1 1`
#這裏-s指定分隔符爲空格,5爲第一個輸出字符,-1爲步長,1爲最後一個字符
do
echo $num
done
例4:使用for循環進行文件批量改名,把jpg改成gif
[root@localhost test]# ls
1.jpg 2.jpg 3.jpg 4.jpg 5.jpg
[root@localhost test]# for a in `ls /root/test/`;do mv $a `echo $a|cut -d . -f1`.gif; done
[root@localhost test]# ls
1.gif 2.gif 3.gif 4.gif 5.gif
例5:for循環在/abc目錄下創建文件abc-1至abc-10
#!/bin/bash
mkdir /abc && cd /abc
for a in {1..10}
do
touch abc-$a
done
例6:for循環批量創建10個普通用戶abc-01至abc-10,密碼設置爲aaa-01至aaa-10
#!/bin/bash
for num in `seq -w 10` #說明:-w以0補充列寬
do
useradd abc-$num
echo "aaa-$num"|passwd --stdin "abc-$num"
done
例7:for循環批量創建用戶密碼爲8位隨機字符串
#先實現8位隨機數的取值
[root@localhost ~]# echo $(date +%N) #%N微秒,每次數字很難相同
099765771
[root@localhost ~]# echo $RANDOM #隨機函數,每次值都不同
11755
[root@localhost ~]# echo $(date +%N)$RANDOM #兩個組合生成更加不同的隨機數
73312156513717
[root@localhost ~]# echo $(date +%N)$RANDOM|md5sum|cut -c 1-8
#把隨機數再使用md5加密,然後取8位即可
e65d36e5
#腳本創建用戶隨機密碼實現:
#!/bin/bash
for num in `seq -w 10`
do
#注意:這裏一定要定義密碼的變量,不然後面echo輸出的密碼就不正確了。
password=$(echo $(date +%N)$RANDOM|md5sum|cut -c 1-8)
useradd abc-$num
echo "aaa-$num"|passwd --stdin "abc-$num"
echo -e "用戶名:abc-$num 密碼:$password" >>/root/user.txt
done
一句話實現方式:
[root@localhost ~]# for num in `seq -w 10`;do password=$(echo $(date +%N)$RANDOM|md5sum|cut –c 1-8);echo -e "用戶名:abc-$num 密碼:$password";done
用戶名:abc-01 密碼:66e7c7ab
用戶名:abc-02 密碼:34dd9e01
用戶名:abc-03 密碼:9accf4e5
用戶名:abc-04 密碼:919cad0a
用戶名:abc-05 密碼:b2c259c0
用戶名:abc-06 密碼:c59e255f
用戶名:abc-07 密碼:bd8bd4f7
用戶名:abc-08 密碼:62b9633d
用戶名:abc-09 密碼:cac00924
用戶名:abc-10 密碼:839317aa
例8:求出(1+2+3...+n)的總和
#!/bin/bash
sum=0
read -p "請輸入一個需要從1加到多少的整數:" num
if [[ $num =~ [^0-9] ]];then
echo "輸入有誤,請輸入大於0的整數!!!"
elif [[ $num -eq 0 ]];then
echo "輸入有誤,請輸入大於0的整數!!!"
else
for i in $(seq 1 $num);do
sum=$[$sum+$i]
done
echo $sum
fi
分析:sum初始值爲0,請輸入一個數,先判斷輸入的是否含有除數字以外的字符,有就報錯;沒有判斷是否爲0,不爲0進入for循環,i的範圍爲1~輸入的數,每次的循環爲sum=sum+i,循環結束,最後輸出sum的值。
例9:計算1+3+5+.....+100所有奇數的和
#!/bin/bash
for ((i=1,sum=0;i<=100;i++));do
[ $[i%2] -eq 1 ] && let sum+=i
done
echo sum=$sum
1.4、for循環中循環體可並行執行,使腳本運行更快
用法:給for循環的循環體加上大括號,然後在大括號後面加上&符號即可
for name in 列表 ;do
{
循環體
}&
done
wait
1.5、for循環並行檢測局域網中存活的主機
搜尋自己指定ip(子網掩碼爲24的)的網段中,UP的ip地址
#!/bin/bash
#說明:此腳本是用來檢測局域網中指定的網段有哪些主機開啓
#用法:直接執行此腳本,然後輸入你想探測的網段地址即可,例如:192.168.10.0網段有哪些主機開啓
read -p "請輸入你想查看主機爲開啓狀態的網段地址[例如:192.168.1.0]:" net
echo $net | egrep -o "\<(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|[25[0-5]])\>"
[ $? -eq 0 ] || (echo "你的輸入有誤,請重新輸入!!!";exit 10)
IP=$(echo $net|egrep -o "^([0-9]{1,3}\.){3}")
for i in {1..254};do
{
# echo $IP$i
ping -c 1 -w 1 $IP$i &> /dev/null && echo "$IP$i 主機開啓"
}&
done
分析:請輸入一個IP地址例192.168.37.234,如果格式不是0.0.0.0 則報錯退出;正確則進入循環,IP變量的值爲192.168.37. i的範圍爲1-254,並行ping 192.168.37.1-154,ping通就輸出此IP爲UP。直到循環結束。
經過測試:上面這個腳本如果循環體大括號後面不加&符號,運行完需要200多秒,加上&之後,運行2秒即可完成。
2、while循環結構語法及實例
2.1、while循環結構語法
while循環控制條件
do
指令
done
循環控制條件;進入循環之前,先做一次判斷;每一次循環之後會再次做判斷;條件爲“true” ,則執行一次循環;直到條件測試狀態爲“false” 終止循環
2.2、特殊用法(遍歷文件的每一行)
while read line; do
循環體
done < /PATH/FROM/SOMEFILE
或
cat /PATH/FROM/SOMEFILE | while read line; do
循環體
done
依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line
2.3、100以內所有正奇數之和
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ];do
if [ $[$i%2] -ne 0 ];then
let sum+=i
let i++
else
let i++
fi
done
echo "100以內所有奇數之和爲:$sum"
分析:sum初始值爲0,i的初始值爲1;請輸入一個數,先判斷輸入的是否含有除數字以外的字符,有,就報錯;沒有當i<100時,進入循環,判斷 i÷2取餘 是否不爲0,不爲0時奇數,sum=sum+i,i+1,爲0,i+1;循環結束,最後輸出sum的值。
2.4、每隔2秒記錄一次系統負載情況
#!/bin/bash
while true
do
uptime
sleep 2
done
提示:while true表示條件永遠爲真,會一直運行,這種我們稱爲守護進程。
2.5、把執行內容追加到log裏,使用微秒爲單位
#!/bin/bash
while [ 1 ]
do
uptime >>./uptime.log
usleep 1000000 #這裏是微秒單位,1秒等於1000000微秒
done
2.6、使用while循環計算從1加到1000000
#!/bin/bash
i=1
sum=0
while((i<=1000000))
do
((sum=sum+i))
((i++))
done
echo "sum=$sum"
以上腳本執行的時間
[root@localhost ~]# time bash 1.sh
sum=500000500000
real 0m15.501s
user 0m14.611s
sys 0m0.737s
2.7、使用計算公式計算從1加到1000000
#!/bin/bash
#快速求和計算公式((sum=n*(n+1)/2))
n=1000000
((sum=$n*($n+1)/2))
echo "sum=$sum"
以上腳本執行的時間
sum=500000500000
real 0m0.024s
user 0m0.006s
sys 0m0.015s
可以看到使用算法公式的效率要比沒有使用算法公式的while快很多倍。
2.8、while讀入文件內容的3種方式
方法1:
exec < FILE
sum=0
while read line
do
cmd
done
方法2:
cat ${FILE_PATH} | while read line
do
cmd
done
方法3:
while read line
do
cmd
done < FILE
3、until循環結構語法及實例
3.1、until循環結構語法
until 循環條件
do
指令
done
until是條件不滿足就一直執行下面的指令,條件滿足就會退出
提示:until應用場合不多,瞭解就行
3.2、監控user1用戶,發現登錄就殺死
#!/bin/bash
until pgrep -u user1 &> /dev/null;do
sleep 1
done
pkill -9 -u user1
分析:每隔1秒掃描,直到發現user1用戶登錄,殺死這個進程,退出腳本,用於監控用戶登錄
3.3、until從1加到100範例
#!/bin/bash
i=1
until ((i>100))
do
((sum=sum+i))
((i++))
done
echo $sum
可以看出until是不滿足條件就執行循環,滿足條件就退出
4、select 循環結構語法及實例
4.1、select循環結構語法
select variable in list
do
循環體命令
done
1、select 循環主要用於創建菜單,按數字順序排列的菜單項將顯示在標準錯誤上,並顯示PS3 提示符,等待用戶輸入
2、用戶輸入菜單列表中的某個數字,執行相應的命令
3、用戶輸入被保存在內置變量 REPLY 中
4、select 是個無限循環,因此要記住用 break 命令退出循環,或用 exit 按 命令終止腳本。也可以按 ctrl+c退出循環
5、select 和 經常和 case 聯合使用
6、與for循環類似,可以省略 in list, 此時使用位置參量
4.2、select循環結構實例
#!/bin/bash
PS3="請輸入你需要選擇的菜單序號:"
select menu in 米飯 包子 餃子 麪條 quit;do
case $REPLY in
1|2)
echo "你選擇的是米飯或包子,價格爲3元每份。"
;;
3|4)
echo "你選擇的是餃子或麪條,價格爲10元每份。"
;;
5)
break
;;
*)
echo "沒有這個選項,請重新選擇!!!"
esac
done
運行結果:
[root@localhost script]# bash select.sh
1) 米飯
2) 包子
3) 餃子
4) 麪條
5) quit
請輸入你需要選擇的菜單序號:2
你選擇的是米飯或包子,價格爲3元每份。
請輸入你需要選擇的菜單序號:3
你選擇的是餃子或麪條,價格爲10元每份。
請輸入你需要選擇的菜單序號:6
沒有這個選項,請重新選擇!!!
請輸入你需要選擇的菜單序號:5
[root@localhost script]#
到此,shell中的四大循環結構就介紹完畢了。