Shell基本文法

來源:互聯網
上載者:User
Shell基本文法

Shell基本文法:
    像進階程式設計語言一樣, Shell也提供說明和使用變數的功能.
對Shell來講,所有變數的取值都是一個字串,Shell程式採用$var的
形式來引用名為var的變數的值。

Shell有以下幾種基本類型的變數:
(1)Shell定義的環境變數:
    Shell 在開始執行時就已經定義了一些和系統的工作環境有關的
變數,使用者還可以重新定義這些變數,常用的Shell環境變數有:
    HOME:    用於儲存註冊目錄的完全路徑名.
PATH:    用於儲存用冒號分隔的目錄路徑名,Shell將按PATH變數
中給出的順序搜尋這些目錄, 找到的第一個與命令名稱一致的可執行
檔案將被執行.
    TERM:    終端的類型.
    UID:    目前使用者的識別字, 取值是由數位構成的字串.
    PWD:    當前工作目錄的絕對路徑名,該變數的取值隨cd命令的
使用而變化。
    PS1:    主提示符, 在特權使用者下, 預設的主提示符是#,在普通
使用者下, 預設的主提示符是$.
    PS2:    在Shell接收使用者輸入命令的過程中,如果使用者在輸入行
的末尾輸入`\` 然後斷行符號, 或者當使用者按斷行符號鍵時Shell判斷出使用者輸
入的命令沒有結束時, 就顯示這個輔助提示符, 提示使用者繼續輸入命
令的其餘部分, 預設的輔助提示符是>。

(2)使用者定義的變數:
    使用者可以按照下面的文法規則定義自己的變數:
    變數名=變數值
    要注意的一點是, 在定義變數時, 變數名前不應加符號$,在引用
變數的內容時則應在變數名前加$; 在給變數賦值時,等號兩邊一定不
能留空格, 若變數中本身就包含了空格,則整個字串都要用雙引號括
起來.
    在編寫Shell程式時, 為了使變數名和命令名相區別,建議所有的
變數名都用大寫字母來表示.
    有時我們想要在說明一個變數並對它設定為一個特定值後就不在
改變它的值時,可以用下面的命令來保證一個變數的唯讀性:
    readonly 變數名
    在任何時候, 建立的變數都只是當前Shell的局部變數,所以不能
被Shell啟動並執行其他命令或Shell程式所利用, 而export命令可以將一
個局部變數提供給Shell執行的其他命令使用, 其格式為:
    export 變數名
也可以在給變數賦值的同時使用export命令:
    export 變數名=變數值
使用 export說明的變數, 在Shell以後啟動並執行所有命令或程式中都可
以訪問到.
可以用unset清除變數值, 格式如下:
unset 變數名

(3)位置參數:
    位置參數是一種在調用 Shell程式的命令列中按照各自的位置決
定的變數, 是在程式名之後輸入的參數. 位置參數之間用空格分隔,
Shell取第一個位置參數替換程式檔案中的$1, 第二個替換$2,依次類
推. $0是一個特殊的變數, 它的內容是當前這個Shell程式的檔案名稱,
所以, $0不是一個位置參數, 在顯示當前所有的位置參數時是不包括
$0的.

(4)預定義變數:
    預定義變數和環境變數相類似,也是在Shell一開始時就定義了的
變數. 所不同的是, 使用者只能根據Shell的定義來使用這些變數,而不
能重定義它. 所有預定義變數都是由$符和另一個符號組成的,常用的
Shell預定義變數有:
    $#    位置參數的數量.
    $*    所有位置參數的內容.
    $?    命令執行後返回的狀態.
    $$    當前進程的進程號.
    $!    後台啟動並執行最後一個進程號.
    $0    當前執行的進程名.
注意:
    $?    用於檢查上一個命令執行是否正確. (在Linux中,命令退出
狀態為0表示該命令正確執行, 任何非0值表示命令出錯.)
    $$    變數最常見的用途是用做暫存檔案的名字以保證暫存檔案不
會重複.

(5)參數置換的變數:
    Shell 提供了參數置換功能以便使用者可以根據不同的條件來給變
量賦不同的值. 參數置換的變數有4種,這些變數通常與某一個位置參
數相聯絡, 根據指定的位置參數是否已經設定來決定變數的取值, 它
們的文法和功能分別如下.
    a. 變數=${參數-word}: 如果設定了參數, 則用參數的值置換變
量的值, 否則用word置換. 即這種變數的值等於某一個參數的值, 如
果該參數沒有設定, 則變數就等於word的值.
    b. 變數=${參數=word}: 如果設定了參數, 則用參數的值置換變
量的值, 否則把變數設定成word, 然後再用word替換參數的值. 注意
位置參數不能用於這種方式,因為在Shell程式中不能為位置參數賦值.
    c. 變數=${參數?word}: 如果設定了參數,則用參數的值置換變
量的值, 否則就顯示word並從Shell中退出, 如果省略了word,則顯示
標準資訊. 這種變數要求一定等於某一個參數的值. 如果該參數沒有
設定, 就顯示一個資訊, 然後退出, 因此這種方式常用於出錯指示.
    d. 變數=${參數+word}: 如果設定了參數,則用word置換變數,
否則不進行置換.
    所有這4種形式中的"參數"既可以是位置參數,也可以是另一個變
量,只是用位置參數的情況比較多.

Shell程式設計的流程式控制制:
    和其他進階程式設計語言一樣,Shell提供了用來控製程序執行流
程的命令, 包括條件分支和迴圈結構, 使用者可以用這些命令建立非常
複雜的程式。
    與傳統語言不同的是, Shell用於指定條件值的不是布爾運算式,
而是命令和字串。

1. 測試命令
    test命令用於檢查某個條件是否成立, 它可以進行數值, 字元和
檔案3個方面的測試, 其測試符和相應的功能分別如下:
(1)數值測試:
    -eq    等於則為真
    -ne    不等於則為真
    -gt 大於則為真
    -ge 大於等於則為真
    -lt 小於則為真
    -le 小於等於則為真

(2)字串測試:
    =    等於則為真
    !=    不相等則為真
    -z字串 判斷字串是否為空白
    -n字串 判斷字串是否不為空白

(3)檔案測試:
    -e檔案名稱 如果檔案存在則為真
    -r檔案名稱 如果檔案存在且可讀則為真
    -w檔案名稱 如果檔案存在且可寫則為真
    -x檔案名稱 如果檔案存在且可執行則為真
    -s檔案名稱 如果檔案存在且至少有一個字元則為真
    -d檔案名稱 如果檔案存在且為目錄則為真
    -f檔案名稱 如果檔案存在且為普通檔案則為真
    -c檔案名稱 如果檔案存在且為字元型特殊檔案則為真
    -b檔案名稱 如果檔案存在且為塊特殊檔案則為真

    另外, Linux還提供了與(!), 或(-o), 非(-a)三個邏輯操
作符, 用於將測試條件串連起來, 其優先順序為: !最高, -a次之,-o
最低。
    同時, bash也能完成簡單的算術運算, 格式如下:
    $[expression]
例如:
    var1=2
    var2=$[var1*10+1]
則var2的值為21.

2. if條件陳述式
    Shell程式中的條件分支是通過if條件陳述式來實現的,其一般格式
為:
    if 條件命令串
    then
        條件為真時的命令串
    else
        條件為假時的命令串
    fi

3. for迴圈
    for迴圈對一個變數的可能的值都執行一個命令序列,賦給變數的
幾個數值既可以在程式內以數值列表的形式提供, 也可以在程式以外
以位置參數的形式提供. for迴圈的一般格式為:

    for變數名    [in數值列表]
    do
        若干個命令列
    done
    變數名可以是使用者選擇的任何字串, 如果變數名是var,則在in之
後給出的數值將順序替換迴圈命令列表中的$var. 如果省略了in, 則
變數var的取值將是位置參數.對變數的每一個可能的賦值都將執行do
和done之間的命令列表。

4. while和until迴圈
    while和until命令都是用命令的返回狀態值來控制迴圈的.While
迴圈的一般格式為:
    while
        若干個命令列1
    do
        若干個命令列2
    done
    只要while的"若干個命令列1"中最後一個命令的返回狀態為真,
while迴圈就繼續執行do...done之間的"若干個命令列2".

    until命令是另一種迴圈結構, 它和while命令相似, 其格式如下
    until
        若干個命令列1
    do
        若干個命令列2
    done

    until迴圈和 while迴圈的區別在於: while迴圈在條件為真時繼
續執行迴圈, 而until則是在條件為假時繼續執行迴圈.
    Shell還提供了true和false兩條命令用於建立無限迴圈結構, 它
們的返回狀態分別是總為0或總為非0。

5. case條件選擇
    if條件陳述式用於在兩個選項中選定一項, 而case條件選擇為使用者
提供了根據字串或變數的值從多個選項中選擇一項的方法, 其格式如
下:
    case string in
    exp-1)
        若干個命令列1
        ;;
    exp-2)
        若干個命令列2
        ;;
        ……
    *)
        其他命令列
    esac

    Shell通過計算字串string的值, 將其結果依次和運算式exp-1,
exp-2等進行比較, 直到找到一個匹配的運算式為止.如果找到了匹配
項, 則執行它下面的命令直到遇到一對分號(;;)為止.
    在case運算式中也可以使用Shell的萬用字元("*", "?", "[ ]").
通常用 *作為case命令的最後運算式以便在前面找不到任何相應的匹
配項時執行"其他命令列"的命令.

6. 無條件控制語句break和continue
    break用於立即終止當前迴圈的執行,而contiune用於不執行迴圈
中後面的語句而立即開始下一個迴圈的執行. 這兩個語句只有放在do
和done之間才有效。

7. 函數定義
    在Shell中還可以定義函數. 函數實際上也是由若干條Shell命令
組成的, 因此它與Shell程式形式上是相似的,不同的是它不是一個單
獨的進程, 而是Shell程式的一部分. 函數定義的基本格式為:
    functionname
    {
        若干命令列
    }
    調用函數的格式為: functionname param1 param2...
    Shell函數可以完成某些例行的工作,而且還可以有自己的退出狀
態, 因此函數也可以作為if, while等控制結構的條件.
    在函數定義時不用帶參數說明, 但在調用函數時可以帶有參數,
此時Shell將把這些參數分別賦予相應的位置參數$1, $2, ...及$*.

8. 命令分組
    在Shell中有兩種命令分組的方法: ()和{}.
    前者當Shell執行()中的命令時將再建立一個新的子進程,然後這
個子進程去執行圓括弧中的命令. 當使用者在執行某個命令時不想讓命
令運行時對狀態集合 (如位置參數, 環境變數, 當前工作目錄等) 的
改變影響到下面語句的執行時, 就應該把這些命令放在圓括弧中, 這
樣就能保證所有的改變只對子進程產生影響, 而父進程不受任何幹擾.
    {}用於將順序執行的命令的輸出結果用於另一個命令的輸入( 管
道方式 ).
    當我們要真正使用圓括弧和花括弧時(如計算運算式的優先順序)
則需要在其前面加上轉義符(\)以便讓Shell知道它們不是用於命令執
行的控制所用.

9. 訊號
    trap命令用於在Shell程式中捕捉訊號,之後可以有3種反應方式:
    (1) 執行一段程式來處理這一訊號.
    (2) 接受訊號的預設操作.
    (3) 忽視這一訊號.
trap對上面3種方式提供了3種基本形式:
    第一種形式的trap命令在Shell接收到與signal list清單中數值
相同的訊號時, 將執行雙引號中的命令串.
    trap 'commands' signal-list
    trap "commands" signal-list
為了恢複訊號的預設操作, 使用第二種形式的trap命令:
    trap signal-list
第三種形式的trap命令允許忽略訊號:
    trap " " signal-list
注意:
    (1) 對訊號11(段違例)不能捕捉,因為Shell本身需要捕捉該訊號
去進行記憶體的轉儲.
    (2) 在trap中可以定義對訊號0的處理(實際上沒有這個訊號),
Shell程式在其終止(如執行exit語句)時發出該訊號.
    (3) 在捕捉到signal-list 中指定的訊號並執行完相應的命令之
後, 如果這些命令沒有將Shell程式終止的話, Shell程式將繼續執行
收到訊號時所執行的命令後面的命令, 這樣將很容易導致 Shell程式
無法終止.
    另外, 在trap語句中, 單引號和雙引號是不同的. 當 Shell程式
第一次碰到trap語句時, 將把commands中的命令掃描一遍. 此時若
commands是用單引號括起來的話,那麼Shell不會對commands中的變數
和命令進行替換, 否則commands中的變數和命令將用當時具體的值來
替換.

運行Shell程式的方法:
    使用者可以用任何編輯程式來編寫Shell程式. 因為Shell程式是解
釋執行的, 所以不需要編譯成目的程式. 按照 Shell編程的慣例, 以
bash為例, 程式的第一行一般為"#!/bin/bash", 其中#表示該行是注
釋, 歎號!告訴Shell運行歎號之後的命令並用文檔的其餘部分作為輸
入, 也就是運行/bin/bash並讓/bin/bash去執行Shell程式的內容.

執行Shell程式的方法有3種:
    1. sh Shell程式檔案名稱
    這種方法的命令格式為:
    bash Shell程式檔案名稱
    這實際上是調用一個新的bash命令解釋程式,而把Shell程式檔案
名作為參數傳遞給它. 新啟動的Shell將去讀指定的檔案,可執行檔
中列出的命令, 當所有的命令都執行完後結束. 該方法的優點是可以
利用Shell調試功能.

    2.sh
    格式為:
    bash< Shell程式名
    這種方式就是利用輸入重新導向,使Shell命令解釋程式的輸入取自
指定的程式檔案.

    3. 用chmod命令使Shell程式成為可執行檔
    一個檔案能否運行取決於該文檔的內容本身可執行且該檔案具有
執行權. 對於Shell程式, 當用編輯器產生一個檔案時,系統賦予的許
可權都是644(rw-r-r--), 因此, 當使用者需要運行這個檔案時,只需要
直接鍵入檔案名稱即可.

    在這3種運行Shell程式的方法中, 最好按下面的方式選擇: 當剛
建立一個Shell程式, 對它的正確性還沒有把握時,應當使用第一種方
式進行調試. 當一個Shell程式已經調試好時,應使用第三種方式把它
固定下來, 以後只要鍵入相應的檔案名稱即可, 並可被另一個程式所調
用.

    4. bash程式的調試
    在編程過程中難免會出錯, 有的時候, 偵錯工具比編寫程式花費
的時間還要多, Shell程式同樣如此.
    Shell程式的調試主要是利用bash命令解釋程式的選擇項. 調用
bash的形式是:
    bash -選擇項 Shell程式檔案名稱
幾個常用的選擇項是:
    -e    如果一個命令失敗就立即退出
    -n    讀入命令但是不執行它們
    -u    置換時把未設定的變數看做出錯
    -v    當讀入Shell輸入行時把它們顯示出來
    -x    執行命令時把命令和它們的參數顯示出來
    上面的所有選項也可以在Shell程式內部用"set -選擇項"的形式
引用, 而"set +選擇項"則將禁止該選擇項起作用.如果只想對程式的
某一部分使用某些選擇項時, 則可以將該部分用上面兩個語句包圍起
來.

    (1) 未置變數退出和立即退出
    未置變數退出特性允許使用者對所有變數進行檢查, 如果引用了一
個未賦值的變數就終止Shell程式的執行. Shell通常允許未置變數的
使用, 在這種情況下, 變數的值為空白. 如果設定了未置變數退出選擇
項, 則一旦使用了未置變數就顯示錯誤資訊, 並終止程式的運行. 未
置變數退出選擇項為-u.
    當Shell運行時, 若遇到不存在或不可執行檔命令,重新導向失敗或
命令非正常結束等情況時, 如果未經重新定向, 該出錯資訊會顯示在
終端螢幕上, 而Shell程式仍將繼續執行. 要想在錯誤發生時迫使
Shell程式立即結束, 可以使用-e選項將Shell程式的執行立即終止.

    (2) Shell程式的跟蹤
    調試Shell程式的主要方法是利用Shell命令解釋程式的-v或-x選
項來跟蹤程式的執行. -v選擇項使Shell在執行程式的過程中,把它讀
入的每一個命令列都顯示出來,而-x選擇項使Shell在執行程式的過程
中把它執行的每一個命令在行首用一個+加上命令名顯示出來.並把每
一個變數和該變數所取的值也顯示出來. 因此,它們的主要區別在於:
在執行命令列之前無-v, 則顯示出命令列的原始內容, 而有-v時則顯
示出經過替換後的命令列的內容.
    除了使用Shell的-v和-x選擇項以外, 還可以在Shell程式內部采
取一些輔助調試的措施. 例如,可以在Shell程式的一些關鍵地方使用
echo命令把必要的資訊顯示出來,它的作用相當於C語言中的printf語
句, 這樣就可以知道程式運行到什麼地方及程式目前的狀態.

bash的內部命令:
    bash命令解釋套裝程式包含了一些內部命令. 內部命令在目錄列
表時是看不見的, 它們由Shell本身提供. 常用的內部命令有: echo,
eval, exec, export, readonly, read, shift, wait和點(.). 下面
簡單介紹其命令格式和功能.

1. echo
命令格式:    echo arg
功能:        在螢幕上顯示出由arg指定的字串。

2. eval
命令格式:    eval args
功能:        當Shell程式執行到eval語句時,Shell讀入參數args,並將
        它們組合成一個新的命令,然後執行.

3. exec
命令格式:    exec命令參數
功能:        當Shell執行到exec語句時,不會去建立新的子進程而是轉
        去執行指定的命令, 當指定的命令執行完時該進程 (也就
        是最初的Shell) 就終止了, 所以Shell程式中exec後面的
        語句將不再被執行.

4. export
命令格式:    export變數名 或:export變數名=變數值
功能:        Shell可以用export把它的變數向下帶入子Shell, 從而
            讓子進程繼承父進程中的環境變數. 但子Shell不能用
            export把它的變數向上帶入父Shell.
注意:        不帶任何變數名的export語句將顯示出當前所有的
            export變數。

5. readonly
命令格式:    readonly變數名
功能:        將一個使用者定義的Shell變數標識為不可變.不帶任何參
            數的 readonly命令將顯示出所有唯讀Shell變數。

6. read
命令格式:    read變數名表
功能:        從標準輸入裝置讀入一行,分解成若干字, 賦值給Shell
            程式內部定義的變數.

7. shift語句
功能:        shift 語句按如下方式重新命名所有的位置參數變數,
            即$2成為$1, $3成為$2...在程式中每使用一次shift語
            句,都使所有的位置參數依次向左移動一個位置,並使位
            置參數$#減1, 直到減到0為止.

8. wait
功能:        使Shell等待在後台啟動的所有子進程結束.wait的返回
            值總是真.

9. exit
功能:        退出Shell程式.在exit之後可有選擇地指定一個數位作
            為返回狀態.

10. "."(點)
命令格式:    . Shell程式檔案名稱
功能:        使Shell讀入指定的Shell程式檔案並依次執行檔案中的
            所有語句.
11. unset
命令格式:    unset [-fv][變數或函數名稱]
功能:        刪除變數或函數.
參數:        -f    僅刪除函數
            -v    僅刪除變數

12. grep    Grep: g(globally) search for a RE(regular
            expression) and p(print) the results.
命令格式:    grep [OPTION]... PATTERN [FILE] ...
參數:        -I: 忽略大小寫
            -c: 列印匹配的行數
            -l: 從多個檔案中尋找包含匹配項
            -v: 尋找不包含匹配項的行
            -n: 列印包含匹配項的行和行標
RE(Regex):
            \    忽略Regex中特殊字元的原有含義
            ^    匹配Regex的開始行
            $    匹配Regex的結束行
            \<    從匹配Regex的行開始
            \>    到匹配Regex的行結束
            [ ]    單個字元; 如[A]即A符合要求
            [ - ]範圍; 如[A-Z]即A, B, C一直到Z都符合要求
            .    所有的單個字元
            *    所有字元, 長度可以為0
結果:        列印輸出匹配行的內容

13. cut
命令格式:    cut [OPTION]... [FILE]...
參數:        -d' '            指定域分隔字元
            -c num1-num2    顯示每行從開頭算起num1到num2的
                            文字.
            -f m-n            顯示第m域到第n域(預設Tab為域分
                            隔符).
功能:        顯示每行從開頭算起num1到num2的文字.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.