shell腳本編程2
今天繼續學習了shell腳本編程,續之前寫的腳本編程1。上次主要學了編程的基礎,腳本格式,變量類型及變量的使用,條件測試,數字運算并且進行了部分練習,因為這部分邏輯思維能力要求不是很高,因此記憶起來難度不是特別大。
從今天開始便進入了流程控制以及函數、數組、高級字符串操作、高級變量等內容的學習,總體來說難度和重要程度都有很大的提升。
一、雜項知識整理
1、在條件判斷的時候,如果有-a和-o存在,兩端的比較使用的括號要用[]而不要用[[]]。在使用[[]]和[]時候注意,[]也支持擴展正則表達式,而[[]]只支持正則表達式。例如:
#!/bin/bash #test 2 # read -p "Please input yes or no: " ANSWER if [ "$ANSWER" == "yes" ] || [ "$ANSWER" == "YES" ];then echo "Your answer is yes!" elif [ "$ANSWER" == "no" -o "$ANSWER" == "NO" ];then echo "Your answer is no!" else echo "Please input a right answer!" fi
2、
[root@localhost shelltest]# ax=25 [root@localhost shelltest]# b=20 [root@localhost shelltest]# echo $ax$b 2520
3、source和bash以及.符號的區別:
source . 兩者可以視作作用等效。通常用于重新執行剛修改的的初始化文檔,影響當前的shell進程環境。source是內置命令,從c shell而來,點符號,從bourne shell而來。
sh/bash 打開新的子shell,讀取并執行Filename中的命令,不影響當前的shell環境,該文件可以沒有執行權限,bash命令是用bash環境來運行,*sh可以用自己的sh類型運行。
二、命令詳解及事例
1、seq命令:print a sequence of numbers產生兩個數之間的所有整數;
-s 指定分隔符,默認是回車
-f 指定格式
-w 指定輸出數字同寬,不能跟-f一起用
步進
[root@localhost shelltest]# seq 2 5 2 3 4 5 [root@localhost shelltest]# seq 1 2 5 1 3 5 [root@localhost shelltest]# seq -s + 1 100 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+3 9+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100
2、if語句:可以嵌套:
單分支:
if 判斷條件;then
條件為真的分支
fi
多分支:
if 判斷條件;then
if true
elif 判斷條件;then
if true
else
all false
fi
3、條件判斷:case語句
case 變量引用 in
PAT)
分支1
;;
PAT)
分支2
;;
*)
默認分支
;;
esac
注意:case支持glob風格的通配符
* 任意長度的任意字符
? 任意單個字符
[] 指定范圍內的任意單個字符
a|b a或b
#!/bin/bash #answer yes or no # read -p "Please input your anwser ,yes or no: " ANS case $ANS in [yY][Ee][Ss]|Y|y) echo "Your answer is $ANS" ;; [nN][Oo]|n|N) echo "Your answer is $ANS" ;; *) echo "error answer" ;; esac
4、for循環:
for 變量名 in 列表;do
循環體
done
執行機制:一次將列表中的元素賦值給變量名;每次賦值后即執行一次循環體;直到列表中的元素耗盡,循環結束。
列表生成方式:(1)直接給出列表
(2)整數列表:(a){start..end} (b)$(seq[#1 步進] #2)若步進為1可省略,起始也可省略。
(3)返回列表的命令:$(COMMAND)
(4)使用glob,如*.sh
(5)變量引用:$@看作不同個變量 $*看作一個整體
5、while循環:
while CONDITION;do
循環體
done
CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之后會再次做判斷;條件為“true”,則執行一次循環;知道條件測試狀態為“false”終止循環。
因此,CONDITION一般應該有循環控制變狼;而此變量的值會在循環體不斷地被修正。
進入條件:CONDITION為真。退出條件:CONDITION為假。
6、until循環:until CONDITION;do
循環體
done
進入條件和退出條件與while相反。
7、循環控制語句:continue;break
continue:提前結束第n層的循環,直接進入新一輪的循環,即結束當前循環,開始新一輪循環
break:結束循環體,執行done或循環命令后的命令;exit停止腳本執行,break為停止循環
關于無限循環:while true;do
循環體
done
until false;do
循環體
done
三、作業及練習
1、判斷用戶輸入的參數是否為正整數:正整數不包括0:第一個數可以為0例如002、032等,第二個數之后可有可無也可以是0,[[]]只支持正則表達式,* 匹配其前面的字符任意次。
#!/bin/bash #test 4 # read -p "Please input a number: " NUM if [[ "$NUM" =~ ^0*[1-9][0-9]*$ ]];then echo "It is a positive integer." else echo "It is not a positive integer." fi
2、使用一個用戶名作為參數,如果指定參數的用戶存在,就顯示其存在,否則添加之,顯示添加的用戶的id號等信息:
#!/bin/bash #test 1 # read -p "Please input a username: " NAME if cut -d: -f1 /etc/passwd | grep "$NAME" &> /dev/null; then echo "username had been added!" else useradd $NAME echo "id $NAME" fi
3、判斷用戶輸入文件路徑,顯示其文件類型。把L或者h放在判斷普通文件f的前面,f判斷鏈接文件的時候,會認做普通文件。
#!/bin/bash #Des:judge the type of a file #test 3 read -p "Please input the of a file: " PATH1 if [ -L "$PATH1" ];then echo "It is a flat file!" elif [ -d "$PATH1" ];then echo "It is a dir file!" elif [ -f "$PATH1" ];then echo "It is a link file!" else echo "other file!" fi
#!/bin/bash #filetype # read -p "Please input a path of a file: " PATH1 file $PATH
4、每隔3秒鐘到系統上獲取已經登錄的用戶的信息;如果發現用戶hacker登錄,則將登錄時間和主機記錄于日志/var/log/login.log中,并提示該用戶退出系統。
#!/bin/bash #silence pavilion #test4 until false;do if w | grep "^hacker" &> /dev/null;then echo `w | grep "^hacker"` >> /tmp/log/login.log echo "logout now!" | write hacker fi sleep 3 done
5、隨機生成10以內的數字,實現猜字游戲,提示比較大小,相等則退出。
#!/bin/bash #test 5 #num game # until false; do read -p "Please input a number between 0 and 10: " NUM RAN=$[RANDOM%10] if [[ "$RAN" -lt "$NUM" ]];then echo "Your number bigger!" continue fi if [[ "$RAN" -gt "$NUM" ]];then echo "Your number smaller!" continue fi if [[ "$RAN" -eq "$NUM" ]];then echo "You win!!" exit 2 fi done
6、編寫腳本。求100以內所有正整數之和
#!/bin/bash #test 6 #silence pavilion # SUM=0 read -p "Please input a number: " NUM until [ "$NUM" -eq 0 ];do SUM=$[$NUM+$SUM] let NUM-- done echo "SUM=$SUM"
7、編寫腳本,通過ping命令探測172.16.250.1-254范圍內的所有主機在線狀態,統計在線主機和離線主機各多少。
#!/bin/bash #name:pinguntil.sh #Des:ping #Author:Silence Pavilion #Version:1.0 #Usage:pinguntil.sh PING=1 NUMUP=0 NUMDOWN=0 until [ $PING = 255 ];do if ping -c 1 -w 2 172.16.250.$PING &> /dev/null;then echo "up" let NUMUP++ else echo "down" let NUMDOWN++ fi let PING++ done echo "UP:$NUMUP DOWN:$NUMDOWN"
8、編寫腳本打印九九乘法表
#!/bin/bash #test 8 #nine nine until # I=1 J=1 until [ "$I" == 10 ];do J=1 until [ "$J" -gt "$I" ];do echo -ne "$J*$I=$[$I*$J]\t" J=$[$J+1] done I=$[$I+1] echo done echo
9、編寫腳本,利用變量RANDOM生成10個隨機數字,輸出這10個數字并顯示其中最大者和最小者
#!/bin/bash #random 10 #test 9 # I=1 MAX=$RANDOM echo $MAX MIN=$MAX until [ "$I" == 9 ];do NUM=`echo $RANDOM` echo $NUM if [[ "$MAX" -le "$NUM" ]];then MAX=$NUM fi if [[ "$MIN" -ge "$NUM" ]];then MIN=$NUM fi let I++ done echo MAX=$MAX echo MIN=$MIN
10、編寫腳本,實現打印國際象棋棋盤。
#!/bin/bash #test 10 #chess #silence pavilion # I=1 J=1 until [ "$I" == 9 ];do echo -ne "$I" J=1 until [[ "$J" == 9 ]];do SUM=$[$I+$J] if [ "$[SUM%2]" -eq 0 ];then echo -ne "\033[43m \033[0m" else echo -ne "\033[45m \033[0m" fi let J++ done echo let I++ done echo " `echo {A..H}`"
11、打印等腰三角形
#!/bin/bash #triangle #test 11 #version 1.3 read -p "Please input a width: " WID WIDTH1=WID-1 NUM=1 NUM1=1 NUM2=$[2*$WID-1] NUM3=1 while [[ "$NUM" -le "$WID" ]];do NUM1=1 NUM3=1 while [[ "$NUM1" -le "$[$WID-$NUM]" ]]; do echo -n " " let NUM1++ done while [[ "NUM3" -le "$[2*$NUM-1]" ]]; do echo -n "*" let NUM3++ done echo let NUM++ done
原創文章,作者:SilencePavilion,如若轉載,請注明出處:http://www.www58058.com/34240