shell的結構化命令

摘要:shell在邏輯流程控制這里會根據設置的變量值的條件或者其余命令的結果跳過少量命令或者者循環執行的這些命令。這些命令通常稱為結構化命令1、if-then語句詳情基本格式if commandthen commandsfi在其余語言中if語句后的對象值為TRUE或者FALSE的等式、bash shell腳本

shell在邏輯流程控制這里會根據設置的變量值的條件或者其余命令的結果跳過少量命令或者者循環執行的這些命令。這些命令通常稱為結構化命令


1、if-then語句詳情

基本格式if commandthen  commandsfi在其余語言中if語句后的對象值為TRUE或者FALSE的等式、bash shell腳本中的if不是這樣的[[email protected] sbin]# sh data.sh 2018年 10月 04日 星期四 18:45:15 CSTecho it worked[[email protected] sbin]# cat data.sh #!/bin/bashif datethenecho echo "it worked"fi [[email protected] sbin]# sh data.sh data.sh:行2: data: 未找到命令[[email protected] sbin]# cat data.sh #!/bin/bashif data ##修改后的thenecho echo "it worked"fi 

bash shell中的if語句在if行定義的命令。假如命令的退出狀態是0(成功執行),將執行then后面的所有命令,假如命令的退出狀態是非0的,那么then后面的命令將不會執行。
($?命令的返回狀態) 0 命令成功結束 1 通用未知錯誤 2 誤用shell命令 126 命令不可執行 127 沒找到命令 128 無效退出參數 128+x Linux 信號x的嚴重錯誤 130 Linux 信號2 的嚴重錯誤,即命令通過SIGINT(Ctrl+C)終止 255 退出狀態碼越界

另一種形式if command;thenconmmandsfi

2、if-then-else語句
那么相應的命名返回狀態為非0時,還需要執行少量需求時就需要多一種選擇
命令的結構式

if command ;then  commandselse  commandsfi

假如命令的返回狀態為非0時,bash shell會移步到腳本的下一條命令。反之就會執行在then部分。

[[email protected] sbin]# cat grep1.sh grep.sh #!/bin/bashuser=nihao ##判斷存在的客戶if grep $user /etc/passwd;then    echo the files for user $user are:else    echo "the user name $user doesn't exist this system"fi#!/bin/bashuser=root ##判斷存在的客戶if grep $user /etc/passwd;then    echo the files for user $user are:else    echo "the user name $user doesn't exist this system"fi[[email protected] sbin]# [[email protected] sbin]# sh grep.sh root:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologinthe files for user root are:[[email protected] sbin]# sh grep1.sh the user name nihao doesn't exist this system

3、嵌套if語句
有時在腳本代碼中需要檢查幾種情況。if-then-else滿足不了時,需要elif。

if command1;then  commandselif command2;then  commandselif command3;then  commandsfi

像這種情況會按循序匹配command1/2/3的執行返回值,第一個返回0時的elif會執行then部分


4、test命令
if語句中除了執行普通的shell命令外,還有一個test命令。
test命令根據退出代碼狀態,判斷條件執行條件為true或者者false。

test的命令格式:test condithoncondition是一系列test命令評估的參數和值。在if-then語句中使用時,命令格式:if test condition;then  commandsfi或者if [ condition ];then  commandsfi方括號里定義了test命令的使用條件。(在括號里括號的開頭和結尾必需加一個空格,否則會報錯)test命令能夠評估一下3類條件:*數值比較*字符串比較*文件比較

4.1數值比較


數值比較.png
[[email protected] sbin]# sh contrast.sh 1 2不相等[[email protected] sbin]# sh contrast.sh 2 2相等[[email protected] sbin]# cat contrast.sh #!/bin/bashif [ $1 -eq $2 ];thenecho 相等elseecho 不相等fi[[email protected] sbin]# 依次類推

在test命令中是不能夠傳浮點數的,命令中會報錯

[[email protected] sbin]# sh folt.sh 3.333folt.sh: 第 4 行:[: 3.333: 期待一元表達式我們不一樣[[email protected] sbin]# cat folt.sh #!/bin/basha=`echo "scale=3;10/3" |bc`echo $a if [ $a >= 3 ];thenecho 一樣elseecho 我們不一樣fi

4.2字符串比較


字符串比較.png
等于判斷[[email protected] sbin]# cat str.sh #!/bin/bashif [ $1 = $2 ];thenecho 一樣elif [ $1 != $2 ];thenecho 不一樣fi[[email protected] sbin]# sh str.sh aa aa一樣[[email protected] sbin]# sh str.sh aa bb不一樣字符串比較長度是的大于或者小于在shell中要特別注意倆點:*大于和小于肯定要轉義,否則shell會解釋成重定向符號,將字符串看出文件名*大于和小于順序于在sort命令中的順序不同[[email protected] sbin]# sh str.sh thccc大于[[email protected] sbin]# sh str.sh thcc不大于[[email protected] sbin]# cat str.sh #!/bin/basha=thccif [ $1 \> $a ];thenecho 大于 else echo 不大于fi[[email protected] sbin]# sh str.sh bb大于[[email protected] sbin]# sh str.sh bbaaa大于[[email protected] sbin]# sh str.sh bbaaaaaa大于[[email protected] sbin]# cat str.sh #!/bin/basha=thccif [ $1 > $a ];then ##要的結果變成了重定向echo 大于 else echo 不大于fi  

4.3字符串大小和文件比較

字符串比較[[email protected] sbin]# cat len.sh #!/bin/bashif [ -n $1 ];thenecho 長度大于零else echo 空fiif [ -z $1 ];thenecho 空else echo 長度大于零fi[[email protected] sbin]# sh len.sh nihao長度大于零長度大于零[[email protected] sbin]# sh len.sh 長度大于零空文件比較-d file 檢查文件能否存在并且是目錄-e file 檢查文件能否存在-f file 檢查問價能否存在并且是一個文件-r file 檢查文件能否可讀-s file 檢查文件能否存在并且不為空-w file 檢查文件能否可寫-x file 檢查文件能否可執行-O file 檢查文件能否存在且被當前客戶擁有-G file 檢查文件能否存在且是當前客戶組file1 -nt file2 檢查 文件1能否比文件2新file1 -ot file2 檢查文件1 能否比文件2舊*案例1 目錄對象文件比較[[email protected] sbin]# sh check.sh /etc/passwd不是目錄對象存在是文件[[email protected] sbin]# cat check.sh #!/bin/bashif [ -d $1 ];thenecho 是目錄elseecho 不是目錄fiif [ -e $1 ];thenecho 對象存在elseecho 對象不存在fiif [ -f $1 ];thenecho 是文件elseecho 不是文件fi  *案例2 文件屬組能否可讀比較[[email protected] sbin]# sh check1.sh /etc/resolv.conf文件存在文件有可讀權限文件是當前的客戶組[[email protected] sbin]# cat check1.sh #!/bin/bashif [ -f $1 ];thenecho 文件存在    if [ -r $1 ];then echo 文件有可讀權限;else null;fi    if [ -G $1 ];then echo 文件是當前的客戶組;else null;fielseecho 文件不存在fi[[email protected] sbin]# ll -a /etc/resolv.conf-rw-r--r--. 1 root root 53 10月  4 17:18 /etc/resolv.conf*案例3 文件或者文件夾能否有數據查詢[[email protected] sbin]# sh null.sh 文件或者文件夾有數據[[email protected] sbin]# sh null.sh kong.txt null[[email protected] sbin]# cat null.sh #!/bin/bashif [ -s $1 ];thenecho 文件或者文件夾有數據elseecho nullfi*案例4 文件能否可寫可執行[[email protected] sbin]# sh wr.sh /etc/passwd可寫null[[email protected] sbin]# chmod u+x wr.sh [[email protected] sbin]# ./wr.sh wr.sh 可寫可執行[[email protected] sbin]# ll -a wr.sh -rwxr--r--. 1 root root 118 10月  5 00:17 wr.sh[[email protected] sbin]# cat wr.sh #!/bin/bashif [ -w $1 ];thenecho 可寫    if [ -x $1 ];then echo 可執行;else echo null;fielse echo 不可寫fi

5、復合條件檢查
在if-then中使用布爾邏輯來合并檢查條件:

 and*[ condition1 ]  && [ condition2 ] or*[ condition1 ]  || [ condition2 ] *案例[[email protected] sbin]# ./wr.sh wr.sh 可寫可執行[[email protected] sbin]# ./wr.sh /etc/passwd可以或者可執行或者都沒有[[email protected] sbin]# cat wr.sh if [ -w $1 ] && [ -x $1 ];then echo 可寫可執行elseecho 可以或者可執行或者都沒有fi [[email protected] sbin]# 

6、if-then的高級特征

*雙圓括號表示數學表達數*雙方括號表示高級字符串解決函數
6.1雙圓括號命令符號val++ 后自增、val--后自減、++val前自增、--val前自減、!邏輯否定、~取反、**取冪、<< 逐為左移、>> 逐位右移、&布爾值與、|布爾值或者、&&邏輯與、||邏輯或者*案例[[email protected] sbin]# sh towbrackets.sh 30900[[email protected] sbin]# sh towbrackets.sh 1小于[[email protected] sbin]# cat towbrackets.sh #!/bin/bashif (( $1 ** 2 > 90));then(( a = $1 ** 2 ))echo $aelse echo 小于fi6.2使用雙方括號格式[[ expression ]]雙括號里用的expression使用在test命令中,給test命令帶來了一個功能叫:模式匹配在模式匹配中可以定義字符串匹配的正則表達式*案例[[email protected] sbin]# sh user.sh 是[[email protected] sbin]# cat user.sh #!/bin/bashif [[ $USER == ro* ]];thenecho 是elseecho 不是fi

7、case命令
語法:

case variable in pattern 1 | pattern2) commands;;pattern 3) commands;;*) commands;;esac

在一組數據中找固定的值,這種情況就需要屢次調用if-then-else語句,如下所示:

[[email protected] sbin]# sh userif.sh 當前客戶是root[[email protected] sbin]# cat userif.sh #!/bin/bashif [ $USER == root ];thenecho 當前客戶是$USER  elif [ $USER == bob ];thenecho 當前客戶是$USERelif [ $USER == boc ];thenecho 當前客戶是$USERelseecho 沒有這個客戶fi 

像這種屢次調用elif的語句可以用case命令簡寫:

[[email protected] sbin]# sh userif.sh root, bob, boc是列表中的root[[email protected] sbin]# cat userif.sh #!/bin/bashlist="root, bob, boc"echo $listcase $USER inroot | bob | boc)echo 是列表中的$USER;;*)echo 沒有列表中的客戶esac[[email protected] sbin]# 

8、for命令
表達式格式是:

for var in listdo   commandsdone

這個命令是一種常見的編程命令。通常用來重復一系列命令,直到滿足一個特定的值或者條件迭代結束。

8.1 讀取列表中的值
for命令的最基本的使用方法是通過for命令中定義的一列值來迭代

[[email protected] sbin]# sh list.sh next start nihaonext start wonext start shinext start shei[[email protected] sbin]# cat list.sh #!/bin/bashfor i in nihao wo shi shei doecho next start $idone [[email protected] sbin]# 

8.2 讀取列表中的復雜值
I don't know if this'll work

[[email protected] sbin]# sh list.sh next start:Inext start:dont know if thisllnext start:work[[email protected] sbin]# cat list.sh #!/bin/bashfor i in I don't know if this'll work  doecho next start:$idone 突然發現在列表中出現了'號,而后出來的值順序發生了變化。像這種情況有倆種處理辦法:*使用轉義字符(反斜杠)來轉義單引號;*使用雙引號來定義使用單引號的值。案例[[email protected] sbin]# sh list.sh next start:Inext start:dont know if thisllnext start:work--------------------------------------------------------------------next start:Inext start:don'tnext start:knownext start:ifnext start:this'llnext start:work-------------------------------------------------------------------next start:I don't know if this'll work-------------------------------------------------------------------next start:Inext start: don'tnext start:knownext start:ifnext start:this'llnext start:work[[email protected] sbin]# cat list.sh #!/bin/bashfor i in I don't know if this'll work  doecho next start:$idone echo --------------------------------------------------------------------for i in I don\'t know if this\'ll work ##1  doecho next start:$idone echo -------------------------------------------------------------------for i in "I don't know if this'll work"  ##2doecho next start:$idone echo -------------------------------------------------------------------for i in "I" " don't" "know" "if" "this'll" "work"  ##2doecho next start:$idone 

8.3 從變量讀取列表

[[email protected] sbin]# sh list1.sh Content viewed root;Content viewed bob;Content viewed gc;Content viewed goc;Content viewed admin;Content viewed tccapache;[[email protected] sbin]# cat list1.sh #!/bin/bashlist="root bob gc goc admin tcc"list=$list"apache"for i in $list do  echo "Content viewed $i;"done

8.4 讀取命令中的值

[[email protected] sbin]# sh list2.sh Content viewed on user roo;Content viewed on user apache;Content viewed on user pas;Content viewed on user bob;Content viewed on user hz;Content viewed on user gouzhi;Content viewed on user wanghao;[[email protected] sbin]# cat list2.sh #!/bin/bashfor i in `cat user.txt`doecho "Content viewed on user $i;"done[[email protected] sbin]# cat user.txt rooapachepasbobhzgouzhiwanghao

8.5 改變shell的字段分割符
在默認情況下,bash shell 的默認分割符是:

*空格;*制表符;*換行符。

修改默認環境變量IFS的值,限制bash shell 看作是字段分割字符的字符。

案例1[[email protected] sbin]# sh list3.sh list this is user roolist this is user apachelist this is user paslist this is user boblist this is user hzlist this is user gouzhilist this is user wanghaolist this is user rooapachepasbobhzgouzhiwanghaolist this is user rooapachepasbobhzgouzhiwanghao[[email protected] sbin]# cat user.txt rooapachepasbobhzgouzhiwanghao因為user.txt文件的格式使用的是換行符,所以只有限定IFS為換行符時執行了遍歷。案例2[[email protected] sbin]# sh test.sh rootx00root/root/bin/bashbinx11bin/bin/sbin/nologin[[email protected] sbin]# cat test.sh #!/bin/bashIFS=$'\n':  #限定多個分割符for i in `cat /etc/passwd |head -n 2`do echo $i done 

8.6 使用通配符讀取目錄
文件通配是生成與指定通配符匹配的文件或者路徑名的過程

[[email protected] sbin]# cat wildcard.sh #!/bin/bashfor i in /var/log/*  do    if [ -d $i ];then        echo 輸出目錄$i    elif [ -f $i ];then        echo 輸出文件$i    fidone[[email protected] sbin]# sh wildcard.sh 輸出目錄/var/log/anaconda輸出目錄/var/log/audit輸出文件/var/log/boot.log輸出文件/var/log/boot.log-20180626輸出文件/var/log/boot.log-20180627輸出文件/var/log/boot.log-20181004輸出文件/var/log/boot.log-20181006輸出文件/var/log/btmp輸出文件/var/log/btmp-20181003輸出目錄/var/log/chrony...

9.C式的for命令
9.1 C語言中的for命令

for (i = 0 ; i < 10 ; i ++){printf ("The next number is %d\n" , i);}一個簡單的自增迭代式[[email protected] sbin]# sh for.sh The next number is 0The next number is 1The next number is 2The next number is 3The next number is 4The next number is 5The next number is 6The next number is 7The next number is 8The next number is 9The next number is 10The next number is 11The next number is 12The next number is 13The next number is 14The next number is 15The next number is 16The next number is 17The next number is 18The next number is 19The next number is 20[[email protected] sbin]# cat for.sh #!/bin/bashfor (( i=0; i <=20; i++ ))do echo "The next number is $i"done 

9.2 使用多個變量
c式的for命令同樣可以使用多個變量迭代:

[[email protected] sbin]# sh for.sh 1 - 102 - 93 - 84 - 75 - 66 - 57 - 48 - 39 - 210 - 1[[email protected] sbin]# cat for.sh #!/bin/bashfor (( i=1, b=10; i <= 10; i++, b-- ))do     echo "$i - $b"done 

10、while 命令
while命令的格式:

while test commanddo   other commanddone案例[[email protected] sbin]# sh while.sh 10987654321[[email protected] sbin]# cat while.sh #!/bin/bashnumber=10while [ $number -gt 0 ]do     echo $number    number=$[ $number - 1 ]done[[email protected] sbin]# 

10.1 使用多個條測試命令

[[email protected] sbin]# sh while.sh 1098765[[email protected] sbin]# cat while.sh #!/bin/bashnumber=10while [ $number -gt 0 ] ##設置大于0    [ $number -ge 5 ] ##設置大于等于5do     echo $number    number=$[ $number - 1 ]done*while命令允許在while語句行定義多條test命令。只有最后一條測試命令的退出狀態是用來決定循環是如何中止的。

11、until命令
這個命令測試的結果和while相反,只測試退出狀態為非0的情況,退出狀態為非0,循環中止。
until的命令格式:

until test commandsdo  other commandsdone案例[[email protected] sbin]# sh -x until.sh + a=100+ '[' 100 -eq 0 ']'+ echo 100100+ a=75+ '[' 75 -eq 0 ']'+ echo 7575+ a=50+ '[' 50 -eq 0 ']'+ echo 5050+ a=25+ '[' 25 -eq 0 ']'+ echo 2525+ a=0+ '[' 0 -eq 0 ']'[[email protected] sbin]# cat until.sh #!/bin/basha=100until [ $a -eq 0 ]doecho $aa=$[ $a - 25 ]done依次判斷直到a=0時退出循環

12、嵌套循環

while和for的嵌套[[email protected] sbin]# sh while-for.sh Input 10input sum的值10input sum的值11Input 9input sum的值9input sum的值10Input 8input sum的值8input sum的值9Input 7input sum的值7input sum的值8Input 6input sum的值6...[[email protected] sbin]# cat while-for.sh #!/bin/basha=10while [ $a -ge 0 ]do echo "Input $a"     for (( i = 0; $i < 2; i++ ))        do            sum=$[ $a + $i ]            echo "input sum的值$sum"        donea=$[ $a - 1]done 

13、文件數據的循環
這里需要結合
*使用嵌套循環 *更改環境變量IFS

...adm:x:3:4:adm:/var/adm:/sbi -value-key: admvalue-key: xvalue-key: 3value-key: 4value-key: admvalue-key: /var/admvalue-key: /sbiValues in / -value-key: /Values in ologi -value-key: ologi[[email protected] sbin]# cat file.sh #!/bin/bash#IFS.OLD=$IFSIFS='\n'for i in `cat /etc/passwd |head -n 4`do    echo "Values in $i -"    IFS=:    for z in $i    do        echo "value-key: $z"    done#IFS=$IFS.OLDdone

14、循環的控制
循環不肯定執行完,對于循環的控制需要用到倆個命令:
break命令: continue命令。
14.1 break命令
這個命令是跳出循環

[[email protected] sbin]# sh break.sh ---------------5------------[[email protected] sbin]# cat break.sh #!/bin/bashfor i in `seq 1 10`do     if [ $i -eq 5 ];then         break       fidone echo ---------------$i------------ ##不加break,正常情況這個$i會輸出1-10這個命令同樣適用于while和until循環

14.2 continue命令
跳出循環后繼續執行

[[email protected] sbin]# sh continue.sh ----------------------1-----------------------------------------2-----------------------------------------3-----------------------------------------4-----------------------------------------6-----------------------------------------7-----------------------------------------8-----------------------------------------9-----------------------------------------11-----------------------------------------12-----------------------------------------13-----------------------------------------14-----------------------------------------15-----------------------------------------16-----------------------------------------17-----------------------------------------18-----------------------------------------19-----------------------------------------20-------------------[[email protected] sbin]# cat continue.sh #!/bin/bashfor i in `seq 1 20`do     case $i in     5 )        continue     ;;     10)        continue     ;;    esacecho ----------------------$i-------------------##這里只是跳過了5和10done  

15、解決循環的輸出
最后,可以在shell腳本中使用管道或者重定向的方式輸出結果。通過在done命令的末尾增加解決命令實現

*重定向[[email protected] sbin]# cat output.txt 輸出文件--/home/all-in-one輸出目錄--/home/hzy輸出目錄--/home/kolla-ansible輸出文件--/home/multinode[[email protected] sbin]# cat yy.sh #!/bin/bashfor i in /home/* doif [ -d $i ];then    echo "輸出目錄--$i"    elif [ -f $i ];then    echo "輸出文件--$i"fidone > output.txt*管道符號[[email protected] sbin]# sh sort.sh 123-----------------aFASDF-----------------aff-----------------asA-----------------fsdf222-----------------s2234-----------------[[email protected] sbin]# cat sort.sh #!/bin/bashfor i in 123 aff s2234 asA aFASDF fsdf222doecho $i-----------------done | sort

END

  • 全部評論(0)
最新發布的資訊信息
【系統環境|】web前端開發需要學習哪些技術(2019-09-17 18:00)
【系統環境|】學習web前端開發是正確的選擇(2019-09-15 16:55)
【系統環境|】干貨整理!零基礎html5網站開發學習步驟方法(保存不后悔)(2019-09-10 16:27)
【系統環境|】「前端入門」前端基本概念(2019-09-07 21:36)
【系統環境|】小白入門學習web前端,這些干貨不能少(2019-09-05 20:59)
【系統環境|】不是計算機專業,哪個專業更適合學習web前端(2019-09-03 20:31)
【系統環境|】入行web前端開發可以做什么工作(2019-09-02 20:51)
【系統環境|】什么是Web前端呢?為什么說web前端開發人員的薪資高、前景好呢?(2019-08-31 20:55)
【系統環境|】2019年Web前端開發的8個趨勢,你知道幾個?(2019-08-29 16:23)
【系統環境|】學習web前端,掌握這些,才有底氣跟面試官提薪資(2019-08-28 15:23)
手機二維碼手機訪問領取大禮包
返回頂部
双色球号码300期遗传走势图