Linux系統程式設計(12)——shell基礎
Shell的作用是解釋執行使用者的命令,使用者輸入一條命令,Shell就解釋執行一條,這種方式稱為互動式(Interactive),Shell還有一種執行命令的方式稱為批處理(Batch),使用者事先寫一個Shell指令碼(Script),其中有很多條命令,讓Shell一次把這些命令執行完,而不必一條一條地敲命令。Shell指令碼和程式語言很相似,也有變數和流程控制語句,但Shell指令碼是解釋執行的,不需要編譯,Shell程式從指令碼中一行一行讀取並執行這些命令,相當於一個使用者把指令碼中的命令一行一行敲到Shell提示符下執行。
由於歷史原因,UNIX系統上有很多種Shell:
sh(Bourne Shell):由SteveBourne開發,各種UNIX系統都配有sh。
csh(C Shell):由Bill Joy開發,隨BSD UNIX釋出,它的流程控制語句很像C語言,支援很多BourneShell所不支援的功能:作業控制,命令歷史,命令列編輯。
ksh(Korn Shell):由David Korn開發,向後相容sh的功能,並且新增了csh引入的新功能,是目前很多UNIX系統標準配置的Shell,在這些系統上/bin/sh往往是指向/bin/ksh的符號連結。
tcsh(TENEX C Shell):是csh的增強版本,引入了命令補全等功能,在FreeBSD、Mac OS X等系統上替代了csh。
bash(Bourne Again Shell):由GNU開發的Shell,主要目標是與POSIX標準保持一致,同時兼顧對sh的相容,bash從csh和ksh借鑑了很多功能,是各種Linux發行版標準配置的Shell,在Linux系統上/bin/sh往往是指向/bin/bash的符號連結[36]。雖然如此,bash和sh還是有很多不同的,一方面,bash擴充套件了一些命令和引數,另一方面,bash並不完全和sh相容,有些行為並不一致,所以bash需要模擬sh的行為:當我們通過sh這個程式名啟動bash時,bash可以假裝自己是sh,不認擴充套件的命令,並且行為與sh保持一致。
使用者在命令列輸入命令後,一般情況下Shell會fork並exec該命令,但是Shell的內建命令例外,執行內建命令相當於呼叫Shell程式中的一個函式,並不建立新的程式。以前學過的cd、alias、umask、exit等命令即是內建命令,凡是用which命令查不到程式檔案所在位置的命令都是內建命令,內建命令沒有單獨的man手冊,要在man手冊中檢視內建命令,應該
$ man bash-builtins
內建命令雖然不建立新的程式,但也會有Exit Status,通常也用0表示成功非零表示失敗,雖然內建命令不建立新的程式,但執行結束後也會有一個狀態碼,也可以用特殊變數$?讀出。
首先編寫一個簡單的指令碼,儲存為script.sh:
#! /bin/sh
cd ..
ls
Shell指令碼中用#表示註釋,相當於C語言的//註釋。但如果#位於第一行開頭,並且是#!(稱為Shebang)則例外,它表示該指令碼使用後面指定的直譯器/bin/sh解釋執行。如果把這個指令碼檔案加上可執行許可權然後執行:
$ chmod +x script.sh
$ ./script.sh
Shell會fork一個子程式並呼叫exec執行./script.sh這個程式,exec系統呼叫應該把子程式的程式碼段替換成./script.sh程式的程式碼段,並從它的_start開始執行。然而script.sh是個文字檔案,根本沒有程式碼段和_start函式,怎麼辦呢?其實exec還有另外一種機制,如果要執行的是一個文字檔案,並且第一行用Shebang指定了直譯器,則用直譯器程式的程式碼段替換當前程式,並且從直譯器的_start開始執行,而這個文字檔案被當作命令列引數傳給直譯器。因此,執行上述指令碼相當於執行程式
$ /bin/sh ./script.sh
以這種方式執行不需要script.sh檔案具有可執行許可權。再舉個例子,比如某個sed指令碼的檔名是script,它的開頭是
#! /bin/sed -f
執行./script相當於執行程式
$ /bin/sed -f ./script.sh
以上介紹了兩種執行Shell指令碼的方法:
$ ./script.sh
$ sh ./script.sh
這兩種方法本質上是一樣的,執行上述指令碼的步驟為:
1、互動Shell(bash)fork/exec一個子Shell(sh)用於執行指令碼,父程式bash等待子程式sh終止。
2、sh讀取指令碼中的cd ..命令,呼叫相應的函式執行內建命令,改變當前工作目錄為上一級目錄。
3、sh讀取指令碼中的ls命令,fork/exec這個程式,列出當前工作目錄下的檔案,sh等待ls終止。
4、ls終止後,sh繼續執行,讀到指令碼檔案末尾,sh終止。
5、sh終止後,bash繼續執行,列印提示符等待使用者輸入。
如果將命令列下輸入的命令用()括號括起來,那麼也會fork出一個子Shell執行小括號中的命令,一行中可以輸入由分號;隔開的多個命令,比如:
$ (cd ..;ls -l)
和上面兩種方法執行Shell指令碼的效果是相同的,cd ..命令改變的是子Shell的PWD,而不會影響到互動式Shell。然而命令
$ cd ..;ls –l
則有不同的效果,cd ..命令是直接在互動式Shell下執行的,改變互動式Shell的PWD,然而這種方式相當於這樣執行Shell指令碼:
$ source ./script.sh
或者
$ . ./script.sh
source或者.命令是Shell的內建命令,這種方式也不會建立子Shell,而是直接在互動式Shell下逐行執行指令碼中的命令。
相關文章
- Linux系統程式設計基礎Linux程式設計
- 講敘Linux系統之Shell程式設計基礎知識(轉)Linux程式設計
- 玩轉Linux – shell 程式設計基礎Linux程式設計
- Shell程式設計-基礎程式設計
- shell程式設計基礎程式設計
- Linux Shell指令碼程式設計-基礎1Linux指令碼程式設計
- Linux-shell程式設計入門基礎Linux程式設計
- shell程式設計基礎二程式設計
- Linux之19——Shell程式設計基礎詳解Linux程式設計
- shell指令碼程式設計基礎指令碼程式設計
- Linux Bash Shell學習(八):shell程式設計基礎——string操作Linux程式設計
- Linux作業系統之Shell程式設計Linux作業系統程式設計
- Linux Bash Shell學習(七):shell程式設計基礎——執行Shell指令碼、functionLinux程式設計指令碼Function
- Linux Shell程式設計(12)——操作符Linux程式設計
- 嵌入式系統程式設計基礎程式設計
- linux程式設計基礎Linux程式設計
- Linux_day06_01_Shell指令碼程式設計_Bash基礎Linux指令碼程式設計
- Linux系統程式設計(13)——Shell的基本語法Linux程式設計
- Linux系統程式設計(15)——shell指令碼語法Linux程式設計指令碼
- Linux系統程式設計(14)——shell常用命令Linux程式設計
- Linux Shell 程式設計基礎詳解——吐血整理,牆裂推薦!Linux程式設計
- Linux Shell程式設計(1)——shell程式設計簡介Linux程式設計
- linux shell 程式設計Linux程式設計
- linux shell程式設計Linux程式設計
- Linux shell 基礎Linux
- Linux Shell程式設計(27)——子shellLinux程式設計
- Python程式設計基礎Task12Python程式設計
- Linux 作業系統程式設計之Shell 問答錄(轉)Linux作業系統程式設計
- Linux 程式設計之Shell程式設計(轉)Linux程式設計
- Linux之shell程式設計Linux程式設計
- Linux Shell程式設計(1)Linux程式設計
- Linux Shell程式設計(2)Linux程式設計
- Shell程式設計基礎學習之六:sed 入門程式設計
- linux系統基礎Linux
- Linux作業系統的Shell程式設計指令碼欣賞(轉)Linux作業系統程式設計指令碼
- Linux下串列埠程式設計基礎Linux串列埠程式設計
- Linux shell基礎3Linux
- Linux shell基礎1Linux