一.概念:
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還提供了 && 和 || 文法,和C語言類似,是以if 語句也可以這樣寫:
<code>index=0</code>
<code>[ index -le 10 ] && {</code>
<code> </code><code>let index++</code>
<code>}</code>
<code>[ index -ge 10 ] || {</code>
這兩個判斷效果是一樣的,都是列印11次hello
PS:-a 與-o 是測試兩個條件然後形成一個結果的,而&& 與 || 則是測試兩條指令的,兩邊都是一個獨立的結果。
(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,如需轉載請自行聯系原作者