Shell指令碼是含有若干UNIX命令或可執行程式的文字檔。
1 運行Shell指令碼
Shell指令碼有兩種運行方式,第一種方式是利用sh命令,把shell指令檔名作為參數。這種執行方式要求shell指令檔具有“可讀”的存取權限。
第二種執行方式是利用chmod命令設定shell指令檔,使shell指令碼具有“可執行”的存取權限。然後直接在命令提示字元下輸入shell指令檔名。
2 退出或出口狀態
一個UNIX進程或命令終止運行時,將會自動地向父進程返回一個出口狀態。如果進程成功執行完畢,將會返回一個數值為0的出口狀態。如果進程在執行過程中出現異常而未正常結束時,將會返回一個非零值得出錯代碼。
在shell指令碼中,可以利用“exit[n]”命令在終止執行shell指令碼的同時,向呼叫指令碼的父進程返回一個數值為n的shell指令碼出口狀態。其中,n必須是一個位於0-255範圍內的整數值。如果shell指令碼是以不帶參數的exit語句結束執行時,shell指令碼的出口狀態就是指令碼中最後執行的一條命令的出口狀態。
UNIX系統中為了測試一個命令或shell指令碼的執行結果,$?內部變數返回之前執行的最後一條命令的出口狀態。
3 調用適當的shell解釋程式
shell指令碼的第一行均包含一個以#!為起始標誌的文本行,這個特殊的起始標誌表示當前檔案包含一組命令,需要提交給指定的shell解釋執行。緊隨#!標誌的是一個路徑名,指向執行當前shell指令檔的命令解釋程式。如:
#!/usr/bin/ksh
如果shell指令碼中包含多個特殊的標誌行,只有一個標誌行起作用。
4 變數
shell變數名可以由任何字母、數字和底線等字元組成,但第一個字元必須是字母或底線。
shell中的所有變數都是字串類型的,shell並不區分變數的類型。
從用途上考慮,變數可以分為內部變數、本地變數、環境變數、參數變數和使用者定義的變數。
內部變數是為便於shell編程而由shell設定的變數。如錯誤類型的ERRNO變數。
本地變數是在代碼塊或函數中定義的變數,且僅在定義的範圍內有效變數。
參數變數是調用shell指令碼或函數時傳遞的變數。
環境變數是為系統核心、系統命令和使用者命令提供運行環境而設定的變數。
使用者定義的變數是為運行使用者程式或完成某種特定的任務而設定的普通變數或臨時變數。
5 變數的賦值
變數的賦值可以採用賦值運算子=實現,其文法格式:variable=value。賦值運算子前後不能有空格,未初始化的變數的值為null,使用下列變數賦值的形式,即可聲明一個未初始化的變數:variable=
6 內部變數
shell提供了豐富的內部變數,為使用者的shell編程提供支援。
PWD,表示當前的工作目錄,其變數值等同於pwd內部命令的輸出。
RANDOM,每次引用這個變數時,將會產生一個均勻分布的0-32767範圍內的隨機整數。
SCONDS,指令碼已經啟動並執行時間(秒)。
PPID,當前進程的父進程的進程ID。
?,$?變數表示最近一次執行的命令或shell指令碼的出口狀態。
7 環境變數
EDITOR,用於確定命令列編輯所用的編輯程式,通常為vi
HOME,使用者主目錄
PATH,指定命令的檢索路徑。
8 變數的引用和替換
假定variable是一個變數,在變數名字前加上“$”首碼符號即可引用變數的值,即使用變數中儲存的值來替換變數名字本身。
引用變數的幾種形式:$variable與${variable}
注意:位於雙引號中的變數可以進行替換但位於單引號中的變數不能進行替換。
9 變數的間接引用
假定一個變數的值是另一個變數的名字,根據第一個變數可以取得第三個變數的值。如:message=hello
hello="good morning" 使用echo "now message=/$$message"將返回now message=good morning。
${var:=value},如果變數var未設定或其值為null,則使用value為變數var賦值,並進行變數替換。
${var=value},不管var是否有值,都將使用value進行替換。
10 位置參數
從命令列上傳遞給shell指令碼的參數,傳遞給函數的參數或通過set命令得到的參數通稱為位置參數。位置參數出現的順序按序號引用$0、$1、$2.....,故稱位置參數。
$0是shell指令檔的名字,由shell進程負責設定$0的參數。
$1是第一個參數,$2是第二個參數....以此類推。但從第十個位置參數開始,必須使用花括弧括起來。如:${10}。
特殊變數$*和$@表示所有的位置參數,$#表示位置參數的總數。
通過set命令來設定位置參數的值,如:set a b c 將設定$1,$2,$3分別為a、b、c。而我們使用命令echo $*將輸出所有已被設定的命令參數的值。
11 變數聲明與類型定義
儘管shell並不嚴格的區分變數的類型,但在korn shell和Bash中,可以使用typeset或declare命令定義變數的類型,並可以在定義時進行初始化。
korn shell使用typeset設定變數的屬性。利用typeset命令的-i選型可以把變數聲明為整數變數。如:
typeset -i number
number=3
echo "number=$number"
12 部分命令介紹
:與true語句不執行任何實際的處理動作,但可用於返回一個出口狀態為0的測試條件。這兩個語句常用於while迴圈結構的無限迴圈測試條件。
echo與print命令,print的功能與echo的功能完全一樣。主要用於顯示各種資訊。
read命令,read語句的主要功能是讀取標準輸入的資料,然後儲存到變數參數中。如果read命令後面有多個變數參數,輸入的資料將按空格分隔單詞順序依次為每個變數賦值。read語句的變數參數後面還可以附加提示字串。如:read data?"please enter data"
set與unset命令,set命令是修改或重新設定位置參數的值。shell規定,使用者不能直接為位置參數賦值。使用不帶參數的set將會輸出所有內部變數。
set --,清除所有的位置參數。
unset命令,用於清除shell變數,把變數的值設定為null。這個命令並不影響位置參數。
expr命令用於計算運算式的值,然後把計算結果送到標註輸出。其中運算式可以是字串比較運算式、整數算術運算式或模式比對運算式。文法格式:expr expression
expr命令支援的整數算術運算運算式:
exp1+exp2,計算運算式exp1和exp2的和
exp1-exp2,計算運算式exp1和exp2的差
exp1/*exp2,計算運算式exp1和exp2的乘積
exp1/exp2,計算運算式exp1和exp2的商
exp1%exp2,計算運算式exp1與exp2的餘數
expr命令支援的字串比較運算式:
str1=str2,比較字串str1等於str2,如果計算結果真,同時輸出1,但傳回值為0。反之計算結果為假,則輸出0,但返回1。
另外的一些比較子:/>、/<、/>=、/<=、!=
let命令取代並擴充了expr命令的整數算術運算。let命令除了expr支援的五種算術運算外,let命令還支援+=、-=、*=、/=、%=
13 數值常數
shell指令碼按十進位解釋字串中的數字字元,除非數字前有特殊的首碼或記號。若數字前有一個0則表示一個八進位的數,0x或0X表示一個十六進位的數。BASE#number表示以BASE(2-64)為底數,以number為的數值。如:
let "oct=032"
echo "oct number=$oct"
let "bin=2#1010"
echo "binary number=$bin"
14 命令替換
命令替換的目的是擷取命令的輸出,為變數賦值或對命令的輸出作進一步的處理。命令替換實現的方法:採用$(...)形式引用命令或使用反向引號引用命令,'command'
如:
today=$(date)
echo $today
刪除檔案filename中包含需要刪除的檔案清單。rm $(cat filename)
15 test語句
test語句與if/then和case結構語句一起,構成了shell編程的控制轉移結構。
test命令的主要功能是計算緊隨其後的運算式,檢查檔案的屬性、比較字串或比較字串內涵的整數值,然後以運算式的計算結果作為test命令的出口狀態。如果test命令的出口狀態為真則返回0,如果為假則返回一個非0的數值。
test命令的文法格式有:test expression或[ expression ],注意方括弧內側的兩邊必須各有一個空格。
[[ expression ]]是一種比[ expression ]更通用的測試結構,也是擴充了test命令。
16 檔案測試運算子
檔案測試主要指檔案的狀態和屬性測試,其中包括檔案是否存在,檔案的類型、檔案的存取權限以及其他屬性等。
檔案屬性測試運算式
-a file,如果給定的檔案存在,則條件測試的結果為真。
-r file,如果給定的檔案存在,且其存取權限是目前使用者可讀的,則條件測試的結果為真。
-w file,如果給定的檔案存在,且其存取權限是目前使用者可寫的,則條件測試的結果為真。
-x file,如果給定的檔案存在,且其存取權限是目前使用者可執行檔,則條件測試的結果為真。
-s file,如果給定的檔案存在,且其大小大於0,則條件測試的結果為真。
-f file,如果給定的檔案存在,且是一個普通檔案,則條件測試的結果為真。
-d file,如果給定的檔案存在,且是一個目錄,則條件測試的結果為真。
-L file,如果給定的檔案存在,且是一個符號連結檔案,則條件測試的結果為真。
-c file,如果給定的檔案存在,且是字元特殊檔案,則條件測試的結果為真。
-b file,如果給定的檔案存在,且是塊特殊檔案,則條件測試的結果為真。
-p file,如果給定的檔案存在,且是命名的管道檔案,則條件測試的結果為真。
f1 -ed f2,如果給定的檔案f1和f2存在且指向的是同一個物理檔案,則條件測試的結果為真。
字串測試運算子
-z str,如果給定的字串的長度為0,則條件的結果為真。
-n str,如果給定的字串的長度大於0,則條件測試的結果為真。要求字串必須加引號。
s1=s2,如果給定的字串s1等同於字串s2,則條件測試的結果為真。
s1!=s2,如果給定的字串s1不等同於字串s2,則條件測試的結果為真。
s1<s2,如果給定的字串s1小於字串s2,則條件測試的結果為真。例:
if[[ "$a"<"Sb" ]]
if[[ "$a"/<"$b" ]],在單方括弧情況下,字元<和>前須加轉義符號。
s1>s2,若給定的字串s1大於字串s2,則條件測試的結果為真。
在比較字串的test語句中,變數或字串運算式前後一定要加雙引號。
整數值測試運算子
test語句中整數值的比較自動採用的是c語言中的atoi()函數,把字元轉換成等價的ASC整數值。所以可以使用數字字串和整數值進行比較。
整數測試運算式:-eq(等於),-ne(不等於),-gt(大於),-lt(小於),-ge(大於等於),-le(小於等於)
17 邏輯運算子
(expression),用於計算括弧中的組合運算式,如果整個運算式的計算結果為真,則測試結果也為真。
!exp,對錶達式進行邏輯非運算,即對測試結果求反。例:test ! -f file1
符號-a或&&表示邏輯與運算,符號-o或||表示邏輯或運算。
==============================================================================
參考拓展:
Linux - SHELL的基礎知識
Linux Shell學習簡單小結(更新中……)
Linux Make(Makefile)由淺入深的學習與樣本剖析
shell if語句 樣本:檔案或目錄是否存在或有執行許可權
linux實現兩個檔案內容相加