shell編程總結

前言:

問題一:什麼是shell?

答:從程序員的角度來看, Shell本身是一種用C語言編寫的程序,從用戶的角度來看,Shell是用戶與Linux操作系統溝通的橋樑。用戶既可以輸入命令執行,又可以利用 Shell腳本編程,完成更加複雜的操作。在Linux GUI日益完善的今天,在系統管理等領域,Shell編程仍然起着不可忽視的作用。深入地瞭解和熟練地掌握Shell編程,是每一個Linux用戶的必修功課之一。

    目前最流行的Shell稱爲bash Shell,bash Shell腳本編程以其簡潔、高效而著稱,多年來成爲Linux程序員和系統管理員解決實際問題的利器。


問題二、爲什麼要使用shell腳本?

答:使用腳本編程語言的好處是,它們多半運行在比編譯型語言還高的層級,能夠輕易處理文件與目錄之類的對象。之所以要使用shell腳本是基於:

    簡單性:shell是一個高級語言,通過它,你可以簡潔地表達複雜的操作。

    可移植性:使用POSIX所定義的功能,可以做到腳本無須修改就可以在不同的系統上執行。

    開發容易:可以在短時間內完成一個功能強大有好用的腳本。


一、初識shell腳本編程

利用vim文本編輯器編寫Shell腳本的格式是固定的,如下:

#!/bin/bash

#This is a shell file

echo "Hello World!"

第一行一定要使用#!指明系統需要哪種shell解釋用戶的shell程序,如:#!/bin/sh,#!/bin/bash,#!/bin/csh,#!/bin/tcsh和#!/bin/ksh等。如果首行沒有這句話,在執行腳本文件的時候,將會出現錯誤。

除首行外,以#開頭的行就是註釋行。

後續的部分就是主程序,Shell腳本像高級語言一樣,也有變量賦值,也有控制語句。

通常shell腳本多以.sh爲後綴。

執行shell的方式有兩種:第一種是爲shell腳本加上可執行權限並執行,第二種是通過bash命令執行shell腳本。


二、shell的基本語法知識

1、變量類別

    (1)本地變量只對當前shell進程有效的變量;對其它shell進程無效,包當前shell進程的子進程;

     VAR_NAME=VALUE

     變量賦值:向變量的存儲空間保存數據

     變量引用:${VAR_NAME}

     "":弱引用,裏面的變量會被替換;

     '':強引用,裏面的所有字符都是字面量,直接輸出;


    (2)環境變量:對當前shell進程及其子shell有效,對其它的shell進程無效;

     定義:export VAR_NAME=VALUE

       導出:export VAR_NAME 

    (當定義了一個本地變量,要在當前shell的子shell進程中使用,可用導出:               export VAR_NAME) 

     撤消變量:unset VAR_NAME(可撤銷本地變量和環境變量) 

      設置只讀變量:readonly VAR_NAME(標誌變量爲不可改變的,即只讀變量)


    (3)局部變量:shell腳本中某代碼片斷有效;通常用於函數本地;

      local VAR_NAME=VALUE(當函數調用結束,局部變量會隨之消失。也能用unset 撤銷局部變量。)


    (4)位置變量

      $1, $2, ..., ${10}(當兩位數或超過兩位數時,最好用{}括起來)


    (5)特殊變量 

               $#:  傳遞到腳本的參數個數

     $*:  以一個單字符串顯示所有向腳本傳遞的參數

     $$:  腳本運行的當前進程ID號

     $!:  後臺運行的最後一個進程的進程ID號

     $@:  與$*相同,但是使用時加引號,並在引號中返回每個參數

     $-:  顯示shell使用的當前選項,與set命令功能相同

     $?:  顯示最後命令的退出狀態,0表示成功,其他任何值都表示有錯誤


    2、變量賦值

    變量=

        任何變量無需事先聲明,可直接使用

        值默認都是字符型

        例如:a=abc, b=3

        a=3(不能寫成 a = 3 ,即中間不能有空格。因在bash中是基於命令行的,中間有空格,bash會把其後的 和 看做選項或參數)

    賦值:

        a=4

    增強型賦值:

        +=, -=, *=, /=, %=

    a=$[$a+1] 相當於 let a+=1  (let a+=1相當於let a=$a+1

    自加:var++, var--, ++var, --var

    

    3、算術運算 

    (1)如何定義整型變量

    let VAR_NAME=INTEGER_VALUE

        例如:let a=3 

    declare -i VAR_NAME=INTEGER_VALUE

        例如:declare -i a=3 

    注意:即使沒有定義爲整型變量,字符型的數字依然可以參與算術運算;bash會執行變量類型的隱式類型轉換;

  

    (2)實現算術運算的方式

    let VAR_NAME=ARITHMATIC_EXPRESSION

    ( 使用let進行算術運算,要使用結果,必須把運算結果存儲在變量中,再去引用變量(不可用` `引用該命令的執行結果) )

    VAR_NAME=$[ARITHMATIC_EXRESSION]

    (不是命令,而是表達式)

    VAR_NAME=$((EXPRESSION))

     (不是命令,而是表達式)

    VAR_NAME=$(expr $num1 + $num2)  

    (使用expr進行算術運算,可用` `引用該命令的執行結果)


    (3)算術運算符

    + :加

    - :減

    * :乘

    / :除

    %:取模,取餘數

    **: 次方,如: 2**2 


   4、條件測試 

    命令執行成功與否即爲條件測試

        test EXPR

        [ EXPR ]

        [[ EXPR ]] 

    比較運算:

        >, <, >=, <=, ==, !=

     

    (1)測試類型:根據比較時的操作數的類型

             整型測試:整數比較

             字符測試:字符串比較

             文件測試:判斷文件的存在性及屬性等

           注意:比較運算通常只在同一種類型間進行

     

    (2)整型測試

        -gt: 大於,例如 [ $num1 -gt $num2 ]

        -lt:  小於

        -ge:  大於等於

        -le:  小於等於

        -eq:  等於

        -nq:  不等於

     

    (3)字符串測試

        雙目

            >      大於,例如[[ "$str1" > "$str2" ]]

            <      小於

            >=     大於等於    

            <=     小於等於

            ==     等於

           !=     不等於

        單目:

              -n String: 是否不空,不空則爲真,空則爲假

              -z String: 是否爲空,空則爲真,不空則假     

        字串測試中的模式匹配:

           [[ "$var" =~ PATTERN ]]


    (4)文件測試: 

          -a FILE :存在爲真,否則爲假;

          -e FILE: 存在則爲真;否則爲假; 

        -f FILE: 存在並且爲普通文件,則爲真;否則爲假;

        -d FILE: 存在並且爲目錄文件,則爲真;否則爲假;

        -L/-h FILE: 存在並且爲符號鏈接文件,則爲真;否則爲假;

        -b: 塊設備

        -c: 字符設備

        -S: 套接字文件

          -p: 命名管道 

        -s FILE: 存在並且爲非空文件則爲值,否則爲假;

        -r FILE :是否可讀

        -w FILE :是否可寫

        -x FILE :是否可執行

 

         file1 -nt file2: file1mtime新於file2則爲真,否則爲假;

        file1 -ot file2:file1mtime舊於file2則爲真,否則爲假;


     5、if語句 

    (1)單分支的if語句:
            if 測試條件; then
                 選擇分支
            fi
     表示條件測試狀態返回值爲0時,則執行選擇分支
         
         或者另外一種格式:
            if 測試條件
            then
                 選擇分支
            fi
     
     (2)雙分支的if語句:
        if 測試條件; then
            選擇分支1
        else
            選擇分支2
        fi 
      兩個分支僅執行其中之一。
      
     (3)多分支的if語句:
        if 條件1; then
            分支1
        elif 條件2; then
            分支2
        elif 條件3; then
            分支3
        ...
        else
            分支n
        fi

     5、case語句

    case 語句:有多個測試條件時,case語句會使得語法結構更明晰
    
    格式:
    case 變量引用 in
    PATTERN1)
        分支1
        ;;
    PATTERN2)
        分支2
        ;;
    ...
    *)
        分支n
        ;;
    esac
     
    PATTERN:類同於文件名通配機制,但支持使用|表示或者;
    a|b: a或者b
    *:匹配任意長度的任意字符
    ?: 匹配任意單個字符
    []: 指定範圍內的任意單個字符 (區分字母大小寫)
    t-size:14px; font-family:'宋體'; " >**: 2**2
    
    
    (分支後的“;;”表示分支結束,不再往下執行,相當於Java中的switch 中的break。如果進入分支1,不加“;;”,則會繼續往下執行。)
    (注意:在bash編程中,case的分支中必須加上“;;”,如果不加“;;”或僅加了“;”,會有語法錯誤!!!)

     6、for語句

    格式:
        for VAR_NAME in LIST    
        do
            循環體
        done 
        
    或者可以寫成:
        for VAR_NAME in LIST ;do
            循環體
        done 
    
    LIST:列表,中間包括一個或多個元素
     
    退出條件:遍歷結束
    
    for的第二種使用格式 :
        for ((初始條件;測試條件;修改表達式)); do
            循環體
        done

    7、while語句

    while  測試條件; do
        循環體
    done
     
    如測試結果爲“真”,則進入循環;退出條件爲,測試條件爲假;

    8、until語句

    until 測試條件; do
        循環體
    done
     
    如果測試結果爲“假”,則進入循環;退出條件爲,測試條件爲真;

     9、函數   

    (函數要先定義,然後才能使用) 

    語法:    
        兩種格式:
        function F_NAME {
            函數體
        }
         
        F_NAME() {
            函數體
        }

    可調用:使用函數名

        函數名出現的地方,會被自動替換爲函數; 


函數中的變量

(1)本地變量:作用域爲整個bash進程
          varname=value
   (2)局部變量:作用域只對當前代碼段有效(只在函數中有效)
          local varname=value (使用local關鍵字定義)

(3)環境變量:作用域爲當前shell進程及其子進程
          export varname=value 


    函數的返回值

        函數的執行結果返回值:代碼的輸出

        函數中的打印語句:echo, print

        函數中調用的系統命令執行後返回的結果

    執行狀態返回值

        函數體中最後一次執行的命令狀態結果

        自定函數執行狀態的返回值:return #

  

    函數可以接受參數

        在函數體中調用函數參數的方式同腳本中調用腳本參數的方式:位置參數

        $1, $2, ...

        $# :參數個數 

         $*, $@ :取所有參數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章