shell腳本編程2:
在上節我們介紹了shell腳本編程,但只是介紹了基礎的內容,下面將為大家介紹shell的腳本的高級用法,判斷與循環.判斷分為兩種:if語句和case語句;循環分為三種:for語句,while語句,until語句,select語句
判斷語句:
在腳本的編寫中,我們要使用大量的數據和命令,但對于使用的數據,我們要想辦法進行驗證,,判斷數據的正確性,來達到我們編寫腳本的目的.于是判斷機制尤為重要,來看下兩個判斷語句.
1.if語句
特點:
選擇執行
判斷條件為真,執行后面語句;否則,執行else后的語句
if可嵌套
語法:
單分支:
if 判斷條件: then
條件為真的分支代碼
fi
雙分支:
if 判斷條件; then
條件為真的分支代碼
else
條件為假的分支代碼
fi
多分支:
if CONDITION1; then
if-true
elif CONDITION2; then
if-ture
elif CONDITION3; then
if-ture
…
else
all-false
fi
注意:逐條件進行判斷,第一次遇為“真”條件時,執行其分支,而后結束整個if語句
實例:
根據命令的退出狀態來執行命令 if ping -c1 -W2 station1 &> /dev/null; then echo 'Station1 is UP' elif grep "station1" ~/maintenance.txt &> /dev/null ;then echo 'Station1 is undergoing maintenance‘ else echo 'Station1 is unexpectedly DOWN!' exit 1 fi
2.case語句
特點:
1.風格:
case支持glob風格的通配符:
*: 任意長度任意字符
?: 任意單個字符
[]:指定范圍內的任意單個字符
a|b: a或b
2.配合死循環使用
語法:
case 變量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
…
*)
默認分支
;;
esac
實例:
case $input in [yY][eE][sS]|[yY]) echo " user enter input is yes" ;; [Nn][oO]|[nN]) echo " user enter input is no" ;; [oO][tT]|[oO]) echo " user enter input is other" ;; *) exit 2 ;; esac
循環語句:
在編寫腳本時,我們會遇到批量的操作,對于行數,數量等有規律的數據,我們可以使用循環的方法,來簡化我們的腳本,也會使我們的的思路更加清晰.來認識下四個循環語句.
循環執行
將某代碼段重復運行多次
重復運行多少次:
循環次數事先已知
循環次數事先未知
有進入條件和退出條件
-
for語句
-
語法
for 變量名 in 列表;do
循環體
done -
執行機制
依次將列表中的元素賦值給“變量名” ; 每次賦值后即執行一次循環體; 直到列表中的元素耗盡,循環結束
-
列表生成方式
(1) 直接給出列表
(2) 整數列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令 $(COMMAND)
(4) 使用glob, 如: *.sh
(5) 變量引用;$@, $ -
特殊用法
雙小括號方法,即((…))格式,也可以用于算術運算
雙小括號方法也可以使bash Shell實現C語言風格的變量操作
#I=10
#((I++))for循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))
do
循環體
done
控制變量初始化:僅在運行到循環代碼段時執行一次
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而后再做條件判斷 -
for (i=1;i<=100;i++) do echo $i done
-
while語句
-
語法
while CONDITION; do
循環體
done -
執行機制
-
until語句
-
語法
until CONDITION; do
循環體
done -
執行機制
CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之后會再次做判斷;條件為“ true”,則執行一次循環;直到條件測試狀態為“ false”終止循環 因此: CONDTION一般應該有循環控制變量;而此變量的值
會在循環體不斷地被修正
進入條件: CONDITION為true;
退出條件: CONDITION為false
c.特殊用法
while循環的特殊用法(遍歷文件的每一行):
while read line; do
循環體
done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line
練習:
掃描/etc/passwd文件每一行,如發現GECOS字段為空,則填充用戶名和單位電話為62985600,并提示該用戶的GECOS信息修改成功
進入條件: CONDITION 為false
退出條件: CONDITION 為true
4.select語句
a.語法
select variable in list
do
循環體命令
done
b.執行機制
select 循環主要用于創建菜單,按數字順序排列的菜單項將顯示在標準錯誤上,并顯示PS3 提示符,等待用戶輸入
用戶輸入菜單列表中的某個數字,執行相應的命令
用戶輸入被保存在內置變量 REPLY 中。
c.特殊用法
select 是個無限循環,因此要記住用 break 命令退出循環,或用 exit 命令終止腳本。也可以按 ctrl+c退出循環。
select 經常和 case 聯合使用
與 for 循環類似,可以省略 in list , 此時使用位置參量
在循環中,有些語句,可以實現對循環過程的控制.
-
continue
用于循環體中
continue [N]:提前結束第N層的本輪循環,而直接進入下一輪判斷;最內層為第1層
while CONDTIITON1; do
CMD1
…
if CONDITION2; then
continue
fi
CMDn
…
done -
break
用于循環體中
break [N]:提前結束第N層循環, 最內層為第1層
while CONDTIITON1; do
CMD1
…
if CONDITION2; then
break
fi
CMDn
…
done -
無限循環
while true; do
循環體
done
until false; do
循環體
done
實戰腳本:
1.
#Description: 掃描/etc/passwd文件每一行,如發現GECOS字段為空,則填充用戶名和單位電話為62985600,并提示該用戶的GECOS信息修改成功 #**************************************************** GECOS=" " while read line;do username=`echo $line|cut -d: -f1` GECOS=`echo $line| cut -d: -f5` if [ -z "$GECOS" ];then usermod -c "$username#62985600" $username &>/dev/null echo "usermod $username over!!!" else echo "$uaername GECOS is exies~~~" fi done < /etc/passwd
2.chmod -rw /tmp/file1,編寫腳本/root/bin/per.sh,判斷當前用戶對/tmp/fiile1文件 是否不可讀且不可寫
#!/bin/bash FileName=/tmp/file1 [ ! -e $FileName ] && echo "file $FileName is no exits" && exit 2 #chmod -rw $FileName &>/dev/null [ -r $FileName -a -w $FileName ] && echo "the file is read and write for one user" || echo "the file is no read and no write for one user"
3、寫一個腳本/root/bin/createuser.sh,實現如下功能:使用一個用戶名做為參數,如果指定參數的用戶存在,就顯示其存在,否則添加之;顯示添加的用戶的id號等信息
#!/bin/bash read -p "enter a username:" input id -u $input &>/dev/null if [ $? -eq 0 ] ;then echo "user $input UID is exits" else echo "user $input is no exits,will useradd $input" useradd $input echo "useradd $input in over!!!" echo "user $input `id $input` " fi
4、寫一個腳本/root/bin/yesorno.sh,提示用戶輸入yes或no,并判斷用戶輸入的是yes還是no,或是其它信息
read -p "pleae enter (yes|no|other):" input if [ "$input" == "yes" ];then echo "user input a yes" elif [ "$input" == "no" ];then echo "user input a no" elif [ "$input" == "other" ];then echo "user input a other" fi ####################################### case $input in [yY][eE][sS]|[yY]) echo " user enter input is yes" ;; [Nn][oO]|[nN]) echo " user enter input is no" ;; [oO][tT]|[oO]) echo " user enter input is other" ;; *) exit 2 ;; esac
5、寫一個腳本/root/bin/filetype.sh,判斷用戶輸入文件路徑,顯示其文件類型(普通,目錄,鏈接,其它文件類型)
read -p "please enter a filedir: " input if [ -f $input ];then echo "the file is a general file" elif [ -d $input ];then echo "the file is a directory" elif [ -h $input ];then echo "the file is a lianjie file" elif [ -b $input ];then echo "the file is a kuaishebei file" elif [ -p $input ];then echo "the file is taojie fiel" fi"
6、寫一個腳本/root/bin/checkint.sh,判斷用戶輸入的參數是否為正整數
read -p "please enter a num(int):" int if [ $int -le 0 &>/dev/null ];then echo "please enter a positive number!!" exit 2 else expr $int + 0 &>/dev/null if [ $? -eq 0 ];then echo "user enter a num is int num " else echo " user enter a num is no int number" fi fi
7、判斷/var/目錄下所有文件的類型
DirName=/var/ filename=`ls -p $DirName` for line in $filename do if [ -f $DirName$line ] ;then echo " $line is a file" elif [ -d $DirName$line ];then echo " $line is a dirstry" fi done
8、 添加10個用戶user1-user10,密碼同用戶名
addnum=[1..10] for i in $addnum; do id user$i &>/dev/null if [ $? -ne 0 ];then useradd user$i |passwd --stdin &>/dev/nul echo "the user$i useradd over!" else echo "Error:the user user$i exits! read -p "dell exit user ?(yes|y| no)" inpu if [ $inpu == y ];then userdel -r user$i &>/dev/null echo "del user$i over!" useradd user$i |passwd --stdin &>/dev/nul echo "the user$i always useradd over!" else exit 7 fi fi done
9、 /etc/rc.d/rc3.d目錄下分別有多個以K開頭和以S開頭的文件;分別讀取每個文件,以K開頭的文件輸出為文件加stop,以S開頭的文件輸出為文件名加start;
“ K34filename stop”
“S66filename start”
dirname=/etc/rc.d/rc3.d/ dir=`ls $dirname` for i in $dir do alpha=`echo $i| grep -o "^[[:alpha:]]"` [ $alpha == "K" ] && echo "$i stop" [ $alpha == "S" ] && echo "$i start" done
10、寫一個腳本,提示輸入正整數n的值,計算1+2+3+…n的
總和
read -p "please enter a int number(n>0 ):" input [ -z $input -a $input -lt 0 ] && echo " num is lt 0 , again enter gt 0 !" && exit 2 sum=0 for i in `seq 1 $input` do sum=$[$sum+$i ] done echo "1 to N has sum is: $sum"
11、 寫一個腳本,提示請輸入網絡地址,如192.168.0.0,判斷輸入的網段中主機在線狀態
#!/bin/bash ip=10.1.252. i=0 up=0 down=0 while [ $i -le 255 ] do ping -c1 -w1 $ip$i &>/dev/null if [ $? -eq 0 ];then echo -e " $ip$i host is \033[32mup\033[0m " up=$[$up+1] else echo -e "$ip$i host is \033[31mdown\033[0m " down=$[$down+1] fi let i++; done echo " up:$up dowm:$down"
12、 打印九九乘法表
for i in {1..9} do for j in $(seq 1 $i) do echo -n -e "${i}x${j}=$[$i*$j]\t" done echo done
13、求100以內所有正整數之和
#1/bin/bash i=0 s=0 while [ $i != 100 ] do i=$[ $i+1 ] sum=$[ $sum+$i ] done echo $sum ############################## sum1=0 for ((i=0;i<=100;i++)) do sum1=$[$sum1+$i] done echo $sum1
14、通過ping命令探測172.16.250.1-254范圍內的所有主機的在線狀態,統計在線主機和離線主機各多少。
15、while循環打印九九乘法表
i=1 j=1 while [ $i -le 9 ] do while [ $j -le $i ] do echo -n -e "${i}x${j}=$[$i*$j]\t" let j++ done j=1 echo let i++; done
16、利用變量RANDOM生成10個隨機數字,輸出這個10數字,并顯示其中的最大者和最小者
## i=0 max=0 min=100 while [ $i -lt 9 ] do num=`echo $[RANDOM%100]` echo $num [ $min -gt $num ] && min=$num [ $max -lt $num ] && max=$num let i++ done echo "big:$max smail:$min " unset i unset max unset min
17、打印國際象棋棋盤
############################################################方法一 #!/bin/bash read -p "please enter a hang num:" hang read -p "please enter a list num:" list i=1 j=1 b="\033[40m \033[0m" w="\033[47m \033[0m" sum="" while [ $i -le $hang ] do while [ $j -le $list ] do if [ $[$i%2] -gt 0 ];then [ $[$j%2] -eq 0 ] && sum=${sum}$b || sum=${sum}$w else [ $[$j%2] -gt 0 ] && sum=${sum}$b || sum=${sum}$w fi let j++ done echo -e "$sum" let i++ j=1 sum="" done ###########################################################方法二 #!/bin/bash read -p " please enter a num(int): " LIE read -p " please enter a num(int:)" HANG a="\033[43m \033[0m" b="\033[40m \033[0m" JSH(){ for((i=1;i<=${LIE};i++)){ [ $[$i%2] -eq 0 ] && echo -ne "$b" || echo -ne "$a" [ $i -eq ${LIE} ] && echo } } OSH(){ for((j=1;j<=${LIE};j++)){ [ $[$j%2] -eq 1 ] && echo -ne "$b" || echo -ne "$a" [ $j -eq ${LIE} ] && echo } } for ((h=1;h<=$HANG;h++)){ [ $[$h%2] -eq 1 ] && JSH || OSH } #####################################################方法三 #!/bin/bash i=1 while [ $i -le 8 ];do j=1 while [ $j -le 8 ];do sum=`expr $i + $j` z=`expr $sum % 2` [ $z -eq 0 ] && echo -ne "\033[41;1m \033[0m"||echo -ne "\033[43;1m \033[0m" let j++ done echo let i++ done
18.每隔3秒鐘到系統上獲取已經登錄的用戶的信息;如果發現用戶hacker登錄,則將登錄時間和主機記錄于日志/var/log/login.log中,并提示該用戶退出系統。
#!/bin/bash clear username=wen while true do echo "3 min scan user login news" sleep 1 echo -e "當前系統的用戶登錄信息:\n `who`" name=`who| grep "$username"` &>/dev/null if [ $? -eq 0 ];then echo "發現$username用戶登錄,已記錄該用戶登錄信息" $name >> /var/log/login.log echo " jilu over exit....." break else echo "the $username is no login" fi done
19.隨機生成10以內的數字,實現猜字游戲,提示比較大或小,相等則退出
#!/bin/bash suiji=$[$RANDOM%10] read -p " please enter a number:" shuru until [[ $suiji -eq $shuru ]]; do #statements [ $shuru -lt $suiji ] && echo " $shuru is to smail" [ $shuru -gt $suiji ] && echo "$shuru is to big" read -p "please enter a number:" shuru done echo "$shuru is == RANDOM, exit"
20.使用until循環
#!/bin/bash i=1 until [ $i -gt 10 ] do echo $i let i++ [ $i -eq 5 ]&& exit echo ++++++++ done echo xxx
21.使用while循環打印三角
[root@wen-7 shangkelianxi]# bash whilesanjiao.sh plesae a nun :6 * *** ***** ******* ********* *********** [root@wen-7 shangkelianxi]# vim whilesanjiao.sh #!/bin/bash read -p "plesae a nun :" lie for i in `seq $lie` do for j in `seq $[ $lie-$i ]` do echo -n " " done for x in `seq $[ $[$i*2]-1]` do echo -n "*" done echo done
原創文章,作者:wencx,如若轉載,請注明出處:http://www.www58058.com/37224