天天看點

shell初涉

一.概念:

Shell俗稱殼(用來差別于核),是一個指令行解釋器,它接收使用者指令,然後調用相應的應用程式。

二.shell的種類:

1.     sh(Bourne Shell):由Steve Bourne開發,各種UNIX系統都配有sh

2.     csh(C Shell):由Bill Joy開發,随BSD UNIX釋出,它的流程控制語句很像C語言,支援很多Bourne Shell所不支援的功能:作業控制,指令曆史,指令行編輯。

3.     ksh(Korn Shell):由David Korn開發,向後相容sh的功能,并且添加了csh引入的新功能, 是目前很多UNIX系統标準配置的Shell,在這些系統上/bin/sh往往是指向/bin/ksh的符号鍊 接。

4.     tcsh(TENEX C Shell):是csh的增強版本,引入了指令補全等功能,在FreeBSD、Mac OS X等系統上替代了csh。

5.     bash(Bourne Again Shell):由GNU開發的Shell,主要目标是與POSIX标準保持一緻,同 時兼顧對sh的相容,bash從csh和ksh借鑒了很多功能,是各種Linux發行版标準配置的Shell,在Linux系統上/bin/sh往往是指向/bin/bash的符号連結。雖然如此,bash和sh還是有很多 不同的,一方面,bash擴充了一些指令和參數,另一方面,bash并不完全和sh相容,有些行 為并不一緻,是以bash需要模拟sh的行為:當我們通過sh這個程式名啟動bash時,bash可以 假裝自己是sh,不認擴充的指令,并且行為與sh保持一緻。

三.shell的運作過程:

linux環境下,打開電腦,電腦就會運作bash。當我們進入終端時,bash會在目前目錄下建立一個子

shell(為了防止惡意指令使bash出錯)。當我們輸入指令時,子shell會先檢測是否為内置指令,如果是,則直接執行,如果不是内置指令,而是普通指令時,子shell會建立一個子程序,在子程序中exec

這個指令的二進制檔案(但如果要執行的不是二進制檔案,而是文本檔案,并且第一行用Shebang(#! /bin/sh)指定了解釋器,則子程序中exec解釋器程式的代碼,并且從解釋器的_start開始執行,而這個文本檔案被當作指令行參數傳給解釋器)。

PS:shell内置指令隻是shell程序中的一個函數。Shell的内建指令用man bash-builtins指令檢視。

四.shell變量:

(1).概述:,Shell變量由全大寫字母加下劃線組成,shell變量分為環境變量和本地變量。

環境變量:環境變量可以從父程序傳給子程序。可以用printenv指令顯示目前shell的環境變量。

本地變量:隻存在于目前shell程序。可以用set指令顯示目前shell程序中定義的所有變量和函數。

PS:環境變量是所有程序都有的,而本地變量是shell特有的。

         導出環境變量用的是export指令。(exprot VARNAME=value)(導出環境變量和定義環境變量可以一步完成)。

          用unset指令删除已定義的環境變量或本地變量。

(2).變量引用:

如果一個變量叫做VARNAME,用${VARNAME}可以表示它的值,在不引起歧義的情況下也可用$VARNAME表示它的值。

如    echo ${VALNAME}

(3).檔案名替換:

以下用于比對的字元稱為通配符(Wildcard),具體如下:

* : 比對0個或多個任意字元

? : 比對一個任意字元

[若幹字元] : 比對方括号中任意一個字元的一次出現

例如:有bash.c    bbsh.c   bcsh.c     bdsh.c檔案

則執行    ls      *.c                        會顯示所有.c檔案

                ls      b?sh.c                 會顯示上面的所有檔案

                ls      b[abc]sh.c          會顯示bash.c    bbsh.c      bcsh.c檔案

(4).指令行替換:

`指令`   或   $( 指令)            (注:``為反引号,與~放在一起)

Shell先執行該指令,然後将輸出結果立刻代換到目前指令行中。

例如:value=`data`

(5).算數替換:

$((  算數運算  ))      用于算術計算,$((   ))中的Shell變量取值将轉換成整數

<code>val=10</code>

<code>echo $(( $val + 3 ))</code>

注:注意空格,指令之間要有空格。

常見的運算符:+,- ,*,  / ,% ,**(幂)

算數運算還可以用let等指令:如    let   val=$val+3

(6).轉義字元:

和C語言類似,\   在Shell中被用作轉義字元。

例如:建立一個 test c.c檔案(test與c中間有空格)

<code>touch test\ \c.c</code>

還有一個比較特殊的符号,即  -   ,但想建立一個以-開頭的檔案時,shell解釋器會把  -  當作選項提示符,此時即使用  \   轉義也是不行的,因為它還是代表   -   的字面意思。是以可以用下面的方法:

<code>touch ./-test.c</code>

./表示目前工作目錄

(7).單引号與雙引号:

和C語言不一樣,Shell腳本中的單引号和雙引号一樣都是字元串的界定符,而不是字元的界定符。單引号用于保持引号内所有字元的字面值,即使引号内的\和回車也不例外, 但是字元串中不能出現單引号。

雙引号與單引号一樣,隻是有一下幾種情況例外:

$ 加變量名可以取變量的值\$表示示$的字面面值

\`表示示`的字面面值

\"表示示"的字面面值

\\表示示\的字面面值 除以上情況之外u反引号仍表示指令替換

\可以起轉移字元的作用

五.條件測試與循環語句:

(1).    test  指令   或      [  指令 ]    

指令test或 [ 可以測試一個條件是否成立,如果測試結果為真,則該指令的Exit Status為0,如果測試結果為假,則指令的Exit Status為1(注意與C語言的邏輯表示正好相反)。

[ -d DIR ] : 如果DIR存在并且是一個目錄則為真

[ -f FILE ] : 如果FILE存在且是一個普通檔案則為真

[ -z STRING ] : 如果STRING的長度為零則為真

[ -n STRING ] : 如果STRING的長度非非零則為真

[ STRING1 = STRING2 ] : 如果兩個字元串相同則為真

[ STRING1 != STRING2 ] : 如果字元串不相同則為真

[ ARG1 OP ARG2 ] : ARG1和ARG2應該是整數或者取值為整數的變量,OP是-eq(等于)- ne(不等于)-lt(小于)-le(小于等于)-gt(大于)-ge(大于等 于)之中的一個

[ ! EXPR ] : EXPR可以是上面中的任意一種測試條件,  !表示示邏輯反

[ EXPR1 -a EXPR2 ] : EXPR1和EXPR2可以是上面中的任意一種測試條件,-a表示示邏輯 與

[ EXPR1 -o EXPR2 ] :EXPR1和EXPR2可以是上面中的任意一種測試條件,-o表示示邏輯 或

(2).  if條件判斷:

格式為:

<code>if</code> <code>指令;then</code>

<code>    </code><code>指令</code>

<code>elif 指令;then</code>

<code>else</code>

<code>fi</code>

PS:  if和then為兩條指令,放在同一行要以 ; 分開,then後面shell會自動續行,把下一條指令放在then後面當作一條指令,由于shell中沒有和c語言一樣的{ }(除函數一樣外),是以要用fi表示if結束。

:   是一個特殊的指令,稱為空指令,該指令不做任何事,但Exit Status總是真

如:

<code>if</code> <code>: ;then</code>

<code>    </code><code>echo </code><code>'hello'</code>

另外,Shell還提供了 &amp;&amp; 和 ||  文法,和C語言類似,是以if 語句也可以這樣寫:

<code>index=0</code>

<code>[ index -le 10 ] &amp;&amp; {</code>

<code>    </code><code>let index++</code>

<code>}</code>

<code>[ index -ge 10 ] || {</code>

這兩個判斷效果是一樣的,都是列印11次hello

PS:-a   與-o   是測試兩個條件然後形成一個結果的,而&amp;&amp; 與  ||  則是測試兩條指令的,兩邊都是一個獨立的結果。

(3).case與esac

<code>case</code> <code>條件 in</code>

<code>    </code><code>結果1)</code>

<code>    </code><code>;;</code>

<code>    </code><code>結果2)</code>

<code>esac</code>

因為shell是弱類型的,并且值是以字元串形式存儲的,是以結果1/結果2等可以是字元串,通配符,字元等(c語言中隻能比對整數或字元常量),另外,每個比對分支可以有若幹 條指令,末尾必須以  ;;   結束,執行時找到第一個比對的分支并執行相應的指令,然後直接跳 到esac之後,不需要像C語言一樣用break跳出。

<code>read val</code>

<code>case</code> <code>$val in</code>

<code>    </code><code>a)</code>

<code>    </code><code>echo </code><code>'this is a'</code>

<code>    </code><code>b)</code>

<code>    </code><code>echo </code><code>'this is b'</code>

<code>    </code><code>*)</code>

<code>    </code><code>echo </code><code>'all is right'</code>

(4).

本文轉自 ye小灰灰  51CTO部落格,原文連結:http://blog.51cto.com/10704527/1789659,如需轉載請自行聯系原作者

繼續閱讀