centos shell腳本編程2 if 判斷 case判斷 shell腳本中的循環 for while shell中的函數 break continue test 命令 第三十六節課
return用在函數中
exit用在shell當中 直接退出整個腳本,整個子shell或當前shell
break退出循環
上半節課
if 判斷
case判斷
shell腳本中的循環
下半節課
for
while
shell中的函數
break
continue
課程大綱(繼續上節課的)
7. if 判斷一些特殊用法
if [ -z $a ] 這個表示當變量a的值為空時會怎么樣 if [ -z $a ];then ehco "\$a is null" ok; fi
if grep -q '123' 1.txt; then 表示如果1.txt中含有'123'的行時會怎么樣
if [ ! -e file ]; then 表示文件不存在時會怎么樣
if (($a<1)); then …等同於 if [ $a -lt 1 ]; then… [ ] 中不能使用<,>,==,!=,>=,<=這樣的符號
8. shell中的case判斷
格式: case 變量名 in
value1) #匹配value1
command
;;
value2) #匹配value2
command
;;
*) #表示匹配任何東西,可以用來檢測非法輸入
commond
;;
esac
在case程序中,可以在條件中使用|,表示或的意思, 比如
2|3)
command
;;
當變量為2或者3時,執行該部分命令。
注意:case語句里面不能寫判斷 case xx in >80 ;; >60 是不能的
案例:
#!/bin/bash read -p "Please input a number: " n if [ -z $n ] then echo "Please input a number." exit 1 fi n1=`echo $n|sed 's/[-0-9]//g'` if [ ! -z $n1 ] then echo "Please input a number." exit 1 #elif [ $n -lt 0 ] || [ $n -gt 100 ] #then # echo "The number range is 0-100." # exit 1 fi if [ $n -lt 60 ] then tag=1 elif [ $n -ge 60 ] && [ $n -lt 80 ] then tag=2 elif [ $n -ge 80 ] && [ $n -lt 90 ] then tag=3 elif [ $n -ge 90 ] && [ $n -le 100 ] then tag=4 else tag=0 fi case $tag in 1) echo "不及格" ;; 2) echo "及格" ;; 3|4) echo "優秀" ;; *) #匹配任何東西,檢測非法輸入 echo "The number range is 0-100." ;; esac 不能寫在 1) 前面 *) echo "The number range is 0-100." ;;
9. shell腳本中的循環
seq命令
默認從1開始
seq 1 20 等價於 seq 20
seq -1 -20
seq 10 -1 1 倒數 -1為步長
for循環 語法結構: for 變量名 in 條件; do … done
案例1:
#!/bin/bash sum=0 for i in `seq 1 100` do sum=$[$sum+$i] echo $i done echo $sum
案例2:
注意:ls跟find不一樣,find會顯示絕對路徑,ls不會,所以要加/etc/$a,或者在腳本開頭加cd /etc/
#!/bin/bash cd /etc/ for a in `ls /etc/` do if [ -d /etc/$a ] then ls -d /etc/$a fi done
結果
# sh for.sh
/etc/abrt
/etc/acpi
/etc/alsa
/etc/alternatives
/etc/audisp
/etc/audit
。。。
案例3:
循環打印一個文本文件,默認以空格為換行符,不是回車,所以還需要用sed處理,不能用cat
#!/bin/bash n=`wc -l 1.txt |awk '{print $1}'` for i in `seq 1 $n` do sed -n "$i"p 1.txt done
while 循環語法結構: while 條件; do … done 死循環用:表示
案例1:
#!/bin/bash while : do load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1` if [ $load -gt 10 ] then top -bn 1|mail -s "load is high: $load" asldkfls@11.com fi sleep 30 done
案例2:
#!/bin/bash while : do read -p "Please input a number: " n if [ -z $n ] then echo "你需要輸入東西" continue fi n1=`echo $n|sed 's/[-0-9]//g'` if [ ! -z $n1 ] then echo "你只能輸入一個純數字" continue fi break done echo $n
break直接結束本層循環;
#!/bin/bash for i in `seq 1 5` do echo $i if [ $i == 3 ] then break fi echo $i done echo aaaaaaa
continue忽略continue之下的代碼,直接進行下一次循環
#!/bin/bash for i in `seq 1 5` do echo $i if [ $i == 3 ] then continue fi echo $i done echo $i
exit 直接退出shell
#!/bin/bash for i in `seq 1 5` do echo $i if [ $i == 3 ] then exit fi echo $i done echo aaaaaaa
10. shell中的函數
函數就是把一段代碼整理到了一個小單元中,並給這個小單元起一個名字,當用到這段代碼時直接調用這個小單元的名字即可。
格式: function f_name() {
command
}
函數必須要放在最前面
函數調用函數,被調用函數需要先在函數前定義
注意:命令和花括號之間要有空格
ping_fun(){ echo 1} 正確應該是 ping_fun(){ echo 1 } 或者 ping_fun(){ echo 1 }
案例1:
#!/bin/bash input() { echo $1 }
案例2:
#!/bin/bash sum() { s=$[$1+$2] echo $s #或者return $s } sum 1 2
echo $?
3
案例3:
#!/bin/bash ip() { ifconfig |grep -A1 "$1 " |grep addr |awk '{print $2}'|awk -F':' '{print $2}' } read -p "Please input the eth name: " e myip=`ip $e` echo "$e address is $myip"
函數里可以export 全局變量
案例4:
猜數字游戲 $RANDOM 生成隨機數 $[$RANDOM%100] 100之內的隨機數 取余 #!/bin/bash n=$[$RANDOM%100] while : do read -p "pleas input a number:" n1 n2=`echo $n1 |sed 's/[0-9]//g'` if [ ! -z $n2 ] then echo "your number is not a number" continue fi if [ $n1 == $n ] then echo "right" echo $n elif [ $n1 -gt $n ] then echo "bigger" continue else echo "smaller" continue fi done
案例5:
#ping函數
#!/bin/bash #write by 2016-2-2 ping_fun(){ if ping -c $1 $2 > /dev/null 2>&1 then return 0 else return 1 fi } host=192.168.12.253 count=2 while : do ping_fun $count $host if [ $? -eq 0 ] then echo "$host is up" else echo "$host is down " |mail -s "$host is down " abc@139.com fi sleep 3 done
11. shell練習題
編寫shell腳本,計算1-100的和;
編寫shell腳本,要求輸入一個數字,然后計算出從1到輸入數字的和,要求,如果輸入的數字小於1,則重新輸入,直到輸入正確的數字為止;
編寫shell腳本,把/root/目錄下的所有目錄(只需要一級)拷貝到/tmp/目錄下;
編寫shell腳本,批量建立用戶user_00, user_01, ... user_100並且所有用戶同屬於users組;
編寫shell腳本,截取文件test.log中包含關鍵詞 ‘abc’ 的行中的第一列(假設分隔符為 ”:” ),然后把截取的數字排序(假設第一列為數字),然后打印出重復次數超過10次的列;
擴展學習:
select用法 http://www.apelearn.com/bbs/thread-7950-1-1.html
擴展閱讀
shell中的select用法 [復制鏈接]
select也是循環的一種,它比較適合用在用戶選擇的情況下。
比如,我們有一個這樣的需求,運行腳本后,讓用戶去選擇數字,選擇1,會運行w命令,選擇2運行top命令,選擇3運行free命令,選擇4退出。輸入序號1、2、3、4
腳本這樣實現:
#!/bin/bash echo "Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit" echo select command in w top free quit #從數字1開始 只能輸入數字 1w 2top 3free 4quit do case $command in w) w ;; top) top ;; free) free ;; quit) exit ;; *) echo "Please input a number:(1-4)." ;; esac done
執行結果如下:
sh select.sh
Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit
1) w
2) top
3) free
4) quit
#? 1
16:03:40 up 32 days, 2:42, 1 user, load average: 0.01, 0.08, 0.08
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 61.135.172.68 15:33 0.00s 0.02s 0.00s sh select.sh
#? 3
total used free shared buffers cached
Mem: 1020328 943736 76592 0 86840 263624
-/+ buffers/cache: 593272 427056
Swap: 2097144 44196 2052948
#?
我們發現,select會默認把序號對應的命令列出來,每次輸入一個數字,則會執行相應的命令,命令執行完后並不會退出腳本。它還會繼續讓我們再次輸如序號。序號前面的提示符,我們也是可以修改的,利用變量PS3即可,再次修改腳本如下:
#!/bin/bash PS3="Please select a number: " echo "Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit" echo select command in w top free quit do case $command in w) w ;; top) top ;; free) free ;; quit) exit ;; *) echo "Please input a number:(1-4)." esac done
如果想要腳本每次輸入一個序號后就自動退出,則需要再次更改腳本如下:
#!/bin/bash PS3="Please select a number: " echo "Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit" echo #換行 select command in w top free quit do case $command in w) w;exit ;; top) top;exit ;; free) free;exit ;; quit) exit ;; *) echo "Please input a number:(1-4).";exit esac done
echo換行
實際上是echo 一個空行
echo 相當於 echo ' '
cat bb.sh
#!/bin/bash echo 'sf' echo echo 'ii'
sh bb.sh
sf
ii
test 命令用法詳解
--http://blog.csdn.net/duguteng/article/details/7725845
基本格式:
test expression
expression為test命令構造的表達式。
這里expression是test命令可以理解的任何有效表達式,該簡化格式將是讀者可能會踫見的最常用格式
返回值:
test命令或者返回0(真) 或者返回1(假).
方式:
表達式判斷
字符串比較
數字比較
文件比較
也就是說
test option file
可以全部改寫成:
[ option file ]
例如:
test –w File
改寫成
[ –w File ]
【示例】
//判斷第一個參數是否為空字符串,不空則打印
if test -n "$1"
then
echo "$1"
fi
測試,放到文件當中
#!/bin/sh
if test -n "$1"
then
echo "$1"
fi
執行
chmod +x test.sh
./test.sh www.linuxpig.com
if test $? -eq 0
判斷返回值是否等於0
shell中自帶的正則匹配
http://bbs.chinaunix.net/thread-4125147-1-1.html
if [[ ! "$arch" =~ x86 ]];then
echo "$2" > /etc/setup/last-mirror
echo "" > /etc/setup/last-arch
例子
<List>
<Job id="1" name="abc"/>
<Job id="2" name="zyz"/>
<Job id="3" name="beew"/>
</List>
想要得到這個結果。
abc | 1
zyz | 2
beew | 3
#!/bin/bash
while read line; do
if [[ $line =~ id=\"([0-9]+).*name=\"([^\"]*) ]]; then
echo "${BASH_REMATCH[2]} | ${BASH_REMATCH[1]}"
fi
done < file
如果你對sed 里的 \1 \2 的用法很熟的話,就應該很快的明白 BASH_REMATCH[1] 和 BASH_REMATCH[2] 代表了什么。
f