- Linux程序設計(第4版)
- (英)Neil Matthew Richard Stones
- 2871字
- 2021-04-09 20:04:40
2.5 作為程序設計語言的shell
現在你已了解了一些基本的shell操作,是時候開始介紹一些真正的shell腳本程序了。編寫shell腳本程序有兩種方式。你可以輸入一系列命令讓shell交互地執行它們,也可以把這些命令保存到一個文件中,然后將該文件作為一個程序來調用。
2.5.1 交互式程序
在命令行上直接輸入shell腳本是一種測試短小代碼段的簡單而快捷的方式。如果你正在學習shell腳本或僅僅是為了進行測試,使用這種方式是非常有用的。
假設你想要從大量C語言源文件中查找包含字符串POSIX的文件。與其使用grep命令在每個文件中搜索字符串,然后再分別列出包含該字符串的文件,不如用下面的交互式腳本來執行整個操作:

請注意,當shell期待進一步的輸入時,正常的$ shell提示符將改變為>提示符。你可以一直輸入下去,由shell來判斷何時輸入完畢并立刻執行腳本程序。
在這個例子中,grep命令輸出它找到的包含POSIX字符串的文件,然后more命令將文件的內容顯示在屏幕上。最后,返回shell提示符。還要注意的是,你用shell變量來處理每個文件,以使該腳本自文檔化。你也可以將變量名起為i,但是變量名file更容易理解。
shell還提供了通配符擴展(通常稱為globbing)。你一定已注意到可以用通配符*來匹配一個字符串。但是你可能不知道可以用通配符?來匹配單個字符,而[set]允許匹配方括號中任何一個單個字符,[^set]對方括號中的內容取反,即匹配任何沒有出現在給出的字符集中的字符。擴展的花括號{}(只能用在部分shell中,其中包括bash)允許你將任意的字符串組放在一個集合中,以供shell進行擴展。例如:

這個命令將列出文件my_fingers和my_toes,它使用shell來檢查當前目錄下的每個文件。當我們在本章結尾詳細介紹grep命令和正則表達式的強大功能時,我們將回過頭來再次研究匹配模式中的這些規則。
有經驗的Linux用戶可能會用一種更有效的方式來執行這個簡單的操作。也許使用如下的命令:

或使用功能相同的另一種命令形式:

此外,下面的命令將輸出包含POSIX字符串的文件名:

在上面的腳本中,你看到shell利用其他命令(如grep和more)來完成主要的工作。shell本身只是允許你將幾個現有的命令結合在一起,以構成一個新的功能強大的命令。你將在后面的腳本示例中看到通配符擴展的多次應用,并且我們還將在本章中介紹grep命令和正則表達式時詳細討論整個擴展的細節。
如果每次想要執行一系列命令時,你都要經過這么一個冗長的輸入過程,將非常令人煩惱。你需要將這些命令保存到一個文件中,即我們常說的shell腳本,這樣你就可以在需要的時候隨時執行它們了。
2.5.2 創建腳本
首先,你必須用一個文本編輯器來創建一個包含命令的文件,將其命名為first,它的內容如下所示:

程序中的注釋以#符號開始,一直持續到該行的結束。按照慣例,我們通常把#放在第一列。在作出這樣一個籠統的陳述之后,請注意第一行#! /bin/sh,它是一種特殊形式的注釋,#!字符告訴系統同一行上緊跟在它后面的那個參數是用來執行本文件的程序。在這個例子中,/bin/sh是默認的shell程序。
請注意注釋中使用的是絕對路徑。考慮到向后兼容性,這個路徑按慣例最好不要超過32個字符,因為一些老版本的UNIX在使用#!時只能使用這個限制之內的字符數,雖然Linux通常不存在這樣的限制。
因為腳本程序本質上被看作是shell的標準輸入,所以它可以包含任何能夠通過你的PATH環境變量引用到的Linux命令。
exit命令的作用是確保腳本程序能夠返回一個有意義的退出碼(在本章的后面將對此進行詳細介紹)。當程序以交互方式運行時,我們很少需要檢查它的退出碼,但如果你打算從另一個腳本程序里調用這個腳本程序并查看它是否執行成功,那么返回一個適當的退出碼就很重要了。即使你從來也沒打算允許你的腳本程序被另一個腳本程序調用,你也應該在退出時返回一個合理的退出碼。請相信自己的腳本程序是有用的,它總有一天會作為其他腳本程序的一部分而被重用。
在shell程序設計里,0表示成功。因為這個腳本程序并不能檢查到任何錯誤,所以它總是返回一個表示成功的退出碼。我們將在本章后面詳細介紹exit命令時,再回過頭來解釋用0表示成功的原因。
請注意,這個腳本沒有使用任何的文件擴展名或后綴。一般情況下,Linux和UNIX很少利用文件擴展名來決定文件的類型。你可以為腳本使用.sh或者其他擴展名,但shell并不關心這一點。大多數預安裝的腳本程序并沒有使用任何文件擴展名,檢查這些文件是否是腳本程序的最好方法是使用file命令,例如,file first或file /bin/bash。你可以使用任何適用于你的工作環境或適合于你的方式。
2.5.3 把腳本設置為可執行
現在你已經有了自己的腳本文件,運行它有兩種方法。比較簡單的方法是調用shell,并把腳本文件名當成一個參數,如下所示:

這可以工作,但如果能像對待其他Linux命令那樣,只輸入腳本程序的名字就可以調用它就更好了。你可以使用chmod命令來改變這個文件的模式,使得這個文件可以被所有用戶執行,如下所示:

當然,這并不是使用chmod命令將一個文件設置為可執行的唯一方式,請用man chmod命令查看它的八進制參數和其他選項用法。
然后你可以用下面的命令來執行它:

你可能會看到一條錯誤信息告訴你未找到命令。這種情況很可能發生,因為shell環境變量PATH并沒有被設置為在當前目錄下查找要執行的命令。要解決這個問題,一種辦法是在命令行上直接輸入命令PATH=$PATH:.或編輯你的.bash_profile文件,將剛才這條命令添加到文件的末尾,然后退出登錄后再重新登錄進來。另外,你也可以在保存腳本程序的目錄中輸入命令./first,該命令的作用是把腳本程序的完整的相對路徑告訴shell。
用./來指定路徑還有另一個好處,它能夠保證你不會意外執行系統中與你的腳本文件同名的另一個命令。
你不應該用這種方法來修改超級用戶(一般其用戶名為root)的PATH變量。這是一個安全方面的漏洞,因為以root用戶身份登錄的系統管理員可能會因此誤調用了某個標準命令的偽裝版本。本書其中一位作者就曾經這樣做過一次,目的當然是為了向系統管理員指出這一點!即使對于普通用戶,把當前目錄包括在PATH變量中也多少有些危險。因此,如果你非常關心系統的安全,最好的辦法是養成在執行當前目錄中的所有命令時,在其前面都加上一個./的好習慣。
在確信你的腳本程序能夠正確執行后,你可以把它從當前目錄移到一個更合適的地方去。如果這個命令只供你本人使用,你可以在自己的家目錄中創建一個bin目錄,并且將該目錄添加到你自己的PATH變量中。如果你想讓其他人也能夠執行這個腳本程序,你可以將/usr/local/bin或其他系統目錄作為添加新程序的適當位置。如果你在系統上沒有root權限,你可以要求系統管理員幫你復制你的文件,當然你首先必須讓他們相信這些程序的價值才行。為了防止其他用戶修改腳本程序,哪怕只是意外地修改,你也應該去掉腳本程序的寫權限。系統管理員用來設置文件屬主和訪問權限的一系列命令如下所示:

注意,你在這里不是修改訪問權限標志的特定部分,而是使用chmod命令的絕對格式,因為你清楚地知道你需要的訪問權限。
如果你愿意,還可以使用chmod命令相對長一些但可能含義更明確的格式,如下所示:

更多chmod命令的詳細資料請參考它的使用手冊。
在Linux系統中,如果你擁有包含某個文件的目錄的寫權限,就可以刪除這個文件。為安全起見,應該確保只有超級用戶才能對你想保證文件安全的目錄執行寫操作。因為目錄只是另一種類型的文件,所以擁有對一個目錄文件寫權限的用戶可以添加和刪除目錄文件中的名稱。
- DevOps:軟件架構師行動指南
- Beginning Java Data Structures and Algorithms
- 小程序實戰視頻課:微信小程序開發全案精講
- Visual C++數字圖像模式識別技術詳解
- 面向STEM的Scratch創新課程
- Silverlight魔幻銀燈
- Expert Android Programming
- Python編程與幾何圖形
- Quantum Computing and Blockchain in Business
- Couchbase Essentials
- 后臺開發:核心技術與應用實踐
- Learning JavaScript Data Structures and Algorithms(Second Edition)
- JavaScript程序設計:基礎·PHP·XML
- Mastering Concurrency Programming with Java 9(Second Edition)
- 并行編程方法與優化實踐