centos shell腳本編程2 if 判斷 case判斷 shell腳本中的循環 for while shell中的函數 break continue test 命令 第三十六節課


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM