本節內容 因為risc-v存在硬體特權級機制,我們又要實現一個可以使得應用程式工作在用戶級,使得操作系統工作在特權級.原因是要保證用戶態的應用程式不能隨意使用內核態的指令,要使用內核態的指令就必須通過操作系統來執行,這樣有了操作系統的控制和檢查,程式不會因為應用程式的問題導致整個操作系統都運行錯誤. ...
11 shell腳本
如果你能在 shell 中輸入命令,你就能編寫 shell 腳本。shell 腳本(也稱為 Bourne shell 腳本)是寫在文件中的一系列命令;shell 會從文件中讀取這些命令,就像在終端中輸入命令一樣。
11.1 shell腳本基礎
Bourne shell 腳本一般以下麵一行開始,表示 /bin/sh 程式應執行腳本文件中的命令。(確保腳本文件開頭沒有空白)。
#!/bin/sh
在本書的其他腳本中,你會看到#!你可以在#/bin/sh行後列出任何希望shell執行的命令。例如
#!/bin/sh
#
# Print something, then run ls
echo About to run the ls command.
ls
shell 會忽略 # 字元之後一行的任何內容。使用註釋來解釋腳本中其他人閱讀代碼時可能難以理解的部分,或在日後重溫代碼時喚起自己的記憶。
與 Unix 系統上的任何程式一樣,您需要為 shell 腳本文件設置可執行位,但同時也必須設置讀取位,以便 shell 能夠讀取文件。最簡單的方法如下:
$ chmod +rx script
這條 chmod 命令允許其他用戶讀取和執行腳本。如果不想這樣,請使用絕對模式 700(有關許可權的複習,請參閱第 2.17 節)。
創建 shell 腳本並設置讀取和執行許可權後,可以將腳本文件放在命令路徑中的某個目錄下,然後在命令行上運行腳本名稱即可。如果腳本位於當前工作目錄中,也可以運行 ./script,或者使用完整路徑名。
例如,運行名為 myscript 的腳本會導致內核運行 /bin/sh myscript。
瞭解了基礎知識後,讓我們來看看 shell 腳本的一些限制。
Shebang,也稱為 Hashbang 或 Hash-bang,是一種特殊的語法,通常出現在文本文件的第一行的前兩個字元:#!。它的作用是指定腳本應該由哪個解釋器來執行。用途如下:
- 明確指定解釋器: 不同的腳本語言有不同的解釋器(比如 Bash、Python、Perl 等)。Shebang 告訴操作系統,應該使用哪個解釋器來運行這個腳本,避免了歧義。
- 直接執行腳本: 有了 Shebang,你就可以直接運行腳本文件,而不需要每次都指定解釋器。
- 跨平臺相容性: 不同的系統可能預設的 shell 或解釋器不同,Shebang 確保了腳本在不同系統上的可移植性。
Shebang 不一定是 #!/bin/sh;它可以構建為運行系統中任何接受腳本輸入的程式,例如 #!/usr/bin/python,以運行 Python 程式。此外,你可能會遇到包含 /usr/bin/env 的不同模式的腳本。例如,你可能會在第一行看到類似 #!/usr/bin/env python 的內容。這會指示env工具運行 python。這樣做的原因很簡單:env 會在當前的命令路徑中查找要運行的命令,因此不需要為可執行文件指定一個標準位置。缺點是命令路徑中第一個匹配的可執行文件可能不是你想要的。
11.1.1 Shell 腳本的局限性
Bourne shell 可以相對輕鬆地操作命令和文件。在第 2.14 節中,我們瞭解了 shell 重定向輸出的方法,這也是 shell 腳本編程的重要元素之一。然而,shell 腳本只是 Unix 編程的一種工具,雖然腳本具有相當強大的功能,但也有其局限性。
shell 腳本的主要優勢之一是可以簡化和自動執行原本可以在 shell 提示符下執行的任務,例如處理成批文件。但是,如果你想剔除字元串、執行重覆的算術計算或訪問複雜的資料庫,或者如果你想使用函數和複雜的控制結構,你最好使用 Python或awk這樣的腳本語言,甚至可能使用 C 這樣的編譯語言(這一點很重要,所以你會在本章中看到)。
最後,要註意 shell 腳本的大小。shell 腳本要簡短。Bourne shell 腳本並不意味著要很大,儘管你無疑會遇到一些龐然大物。
11.2 引用和字面量
在使用 shell 和腳本的過程中,最令人困惑的一點就是不知道什麼時候以及為什麼要使用引號(quotes)和其他標點符號。假設您想列印 $100 字元串,請執行以下操作:
$ echo $100
00
$ echo "$100"
00
$ echo '$100'
$100
11.2.1 字面量
當你使用引號時,通常是要創建一個字面形式,即 shell 在將其傳遞到命令行之前不應分析(或試圖更改)的字元串。除了剛纔例子中的 $ 之外,當你想將 * 字元傳遞給 grep 等命令而不是讓 shell 展開它,以及當你需要在命令中使用分號 (