天天看點

Bash程式設計(二)

<code>一、Bash腳本程式設計風格</code>

<code>二、Bash條件測試:</code>

<code>三、腳本的狀态傳回值       </code>

<code>四、練習腳本:</code>

<code>五、</code><code>if</code> <code>語句</code>

一、Bash腳本程式設計風格

    腳本格式:

    #!/bin/bash

    #description: say hello

    #version 0.0.1        //注釋資訊    

    #author:xiaoming        //代碼注釋

    #date:2017-01-01

    縮進:适度添加空白行;

    文法:程式設計文法格式、庫調用(類庫)、算法、資料結構

    程式設計思想:

        問題空間--&gt;解空間

    變量:

        局部變量:目前shell

        本地變量:local,函數内部

        環境變量:目前shell及其子程序

        位置參數變量:$1,$2,$3

        特殊變量:$#,$@

    變量的資料類型://弱類型,預設都為字元型

        字元型

        數值型

    算數運算:+,-,*,/,%,**

        expr,let

        let VAR=expression

        $((expression))

        $[expression]

        var=$(expr argu1 + argu2)  //一個小括号,指令引用

    注意:有些時候,乘法符号需要轉義    

    animal=dog;echo "${animal}s" //用花括号分開即可

    PATH=“$PATH:/usr/locale/apache/bin" //引用原有的值,然後重新指派

    增強型指派:變量做某種算術運算後回至此變量中

        declare -i a=1 //

        i=$[$i+1]

        let i+=2 //這樣也可以的:增強型複制機制

        let +=,-=,*=,/=,%=  //一般使用let進行

        let ++,--  //自己加上/減去 1

            let var=$[$var+1]

            let var+=1

            let var++

腳本1:添加user1

    # first_scrpit

    id user1 &amp;&gt; /dev/null || useradd user1

    id user2 &amp;&gt; /dev/null || useradd user2

    user_id1=$(id -u user1)

    user_id2=$(id -u user2)

    id_sum=$[$user_id1+$user_id2]

    echo "sum is :$id_sum"

練習:

    1.寫一個腳本,計算/etc/passwd檔案中第10個使用者和第20個使用者的id号之和

    2.計算/etc/rc.d/init.d/functions和/etc/inittba檔案的空白行數之和

    1.

        id1=$(head -10 /etc/passwd | tail -1 | cut -d: -f3}

        id2=$(head -20 /etc/passwd | tail -1 | cut -d: -f3}

    2.

        b1=$(grep "^$" /etc/rc.d/init.d/functions  | wc -l)

        b1=$(grep "^[[:space:]]*$" /etc/rc.d/init.d/functions  | wc -l)

二、Bash條件測試:

    判斷某需求是否滿足,需要測試機制來實作

    ||,&amp;&amp;,! //或,非,與

    測試方法:

        1.執行指令,并利用指令狀态傳回值來判斷

            0:成功

            1-255:失敗

            echo $?

        2.測試表達式

            test -[d,e,f,h,p,r,s,S,w,N] a.txt

                d目錄,f普通檔案,e存在,h|-L符号檔案,

                r可讀,w可寫,-s非空,-S套接字,-N上次讀取之後修改過

            [ expression ] 

            ` expression `

            注意:expression兩端必須有空格,否則為文法錯誤

    bash測試類型:

        數值測試

        字元串測試

        檔案測試

    1.數值測試:數值比較

        -eq,-gt,-lt

        -ge,-le,-ne

            test 3 -gt 4 &amp;&amp; echo True || echo false    

    2.字元串測試:根據ascii表,盡可能定義在` `中

        == 是否相當

        &gt;         

        《    

        !=    是否不等于

        =-  :左側的字元串是否能夠被右側的pattern比對

            name=tom; [[ "$name" =~ t ]] ;echo $? //tom是否包含 t字母

        //單目

        -z “STRING” 判斷子串是否為空,空則為真,否則為假

        -n “STRING” 是否不空

            [ -n "$name" ];echo $?

        注意:[[ “a” &gt; “b” ]] ;echo $?

            //一定要使用兩個中括号,否則會出錯

            (1)字元串要加引用

            (2)要使用` `

    3.檔案測試

        d目錄,-S套接字,-p 管道檔案

        f普通檔案,

        a|e存在,

        h|-L符号檔案,

        -b 塊裝置檔案

        -s非空,

        -N上次讀取之後修改過 //上次讀取後,是否被修改過

    4.檔案權限測試:

        r可讀,是否存在且對目前使用者可讀

        w可寫,

        x可執行    

        -g 是否存在,并且擁有sgid權限

        -u 是否存在,并且擁有suid權限

        -k sticky權限

            [ -u /bin/passwd ] ; echo $?

    5.從屬關系測試

        -O FILE 目前使用者是否為檔案的屬主

        -G FILE 目前使用者是否為屋内安的屬組

    6.雙目運算

        FILE1 -ef FILE2 //file1與file2是否指向同一個fs的相同inode

        file1 -nt filr2 //file1是否新于file2

        file1 -ot file2 //file1是否舊于file2

    7.組合測試:

        邏輯運算:

            第一種方式:

                a &amp;&amp; b 

                a || b

                ! a //取反

        [ -O file ] &amp;&amp; [ -r file ] //目前使用者為屬主并且可讀

        [ -O file -a -x file ]

        expression -a expression2 //

        expression -o expression2 

        ! expression

        test "a" != "$HOME" -a 3 -ge 4 ; echo $?

        [ ! \( "a" = "$HOME" -o 3 -lt 4 \) ]; echo $?

        [ ! \( "a" = "$HOME" -o '(' 3 -lt 4 ')' ")" ]; echo $?

三、腳本的狀态傳回值

    預設是腳本中執行的最後一條指令的狀态傳回值

    自定義狀态傳回值

    exit [n] //自定義狀态傳回值,狀态碼

    注意:shell程序遇到exit會終止,是以整個腳本将會結束

        一般判斷條件是否滿足,再執行exit

注意:XShell的鎖定和接觸鎖定

    vim 

    ctrl + s 鎖定後,

    ctrl + q 取消鎖定

四、練習腳本:

腳本1:

    将目前主機名稱儲存至hostName變量中:

    主機名為空,或者為localhost.localdomain,則将其設定為www.mt.com

#!/bin/bash

hostName=$(hostname)

[ -z "$hostName" -o "$hostName"=="localhost.localdomain" -o hostName=="localhost" ]  &amp;&amp; hostname www.xt.com

注意:

    //必須是 [] ,而不能是 ` ` ,或者 

    //== 前後不需要空格

    // [ ] 前後都需要空格,

    //$hostname 得需要“ ”    

    //[ ** -o|-a| ** ] 判斷内部 // &amp;&amp; ||  ! 判斷[]外部

腳本2.向腳本傳遞參數

    位置參數變量;

    引用:

        $1,$2,...$(12)

    shift 輪替

        shift n :位置參數變量

    特殊變量:

        $0:腳本檔案名

        $#: 擷取參數個數總和

        $*: 所有參數

        $@: 所有參數

引用變量計算數值

bash sum.sh 23 78 

#

echo $[$1 + $2]

//判斷檔案空白行行數

[ $# -lt 2 ] &amp;&amp; echo "At least two files" &amp;&amp; exit 1

b1=$(grep "^$" $1 | wc -l)

b2=$(grep "^$" $2 | wc -l)

echo "sum of blank is : $[b1+b2]"

五、if 語句

過程式程式設計語言的代碼執行順序

    順序執行:逐條執行

    選擇執行:

        代碼有一個分支:條件滿足則執行

            兩個以上的分支:隻會執行其中一個滿足條件的執行

    循環執行:

        代碼片段(循環體)要執行0,1或多個來回

        if 測試條件 ; then  //需要分号

            代碼分支

        fi

        if 測試條件        //then單獨分行,不需要分号

        then

        雙分支if語句

        if 測試條件; then

            條件為真時運作

        else 

            條件為假時執行

腳本3:通過參數傳遞一個使用者名給腳本,此使用者不存在時添加該使用者

if [ $# -lt 1 ]; then

    echo "At least one user_name"

    exit 1

fi

if ! [ grep "$1\&gt;" /etc/passwd ] &amp;&gt; /dev/null; then

    useradd $1

    echo $1 | passwd --stdin $1

    echo "USER $1 added succeed!"

    exit 0

else

    echo "Failure ..."

    exit1

腳本4:通過鍵盤給定兩個數字,輸出其中較大的值

if [ $# -lt 2 ] ; then

    echo "Two intergers."

    exit 2

if [ $1 -ge $2 ] ;then

    echo "max number is: $1"

    echo "max number is: $2"

腳本5:通過指令參數傳遞給定兩個檔案名,如果某檔案不存在,則結束腳本

    傳回每個檔案的行數,并說明其中行數最多的檔案

[root@wolf test]# cat 2.sh 

#AUthor xt 

#date 2017-07-22

declare -i f1 f2

if [ $# -lt 2 ] ; then echo "At least two files " exit 1 ; fi

#if  [ ! -f $1 ] ||  [ ! -f $2 ] ; then 

if  ! [ -f $1 -a  -f $2 ] ; then 

    echo "At least one is not a primary file" exit 2 ; 

else 

    f1=$(wc -l $1 | cut -d' ' -f1)

    f2=$(wc -l $2 | cut -d' ' -f1)

    if [ $f1 -gt $f2 ] ;then 

        max=$f1

    else 

        max=$f2 

    fi

    echo "First file's line is $f1"    

    echo "Second file's line is $f2"    

    echo "Max  is line is $max"    

本文轉自MT_IT51CTO部落格,原文連結:http://blog.51cto.com/hmtk520/1950102,如需轉載請自行聯系原作者

繼續閱讀