
前言:
現在在我們已經知道了Linux系統和命令列的基礎知識,是時候開始編程了,本章討論撰寫 shell腳本的基礎知識,在開始撰寫自己的shell腳本前,你必須了解的基本概念都在這里,
一、多個shell命令的使用
這就是一個最簡單的shell腳本,運行了兩個shell命令,who命令先運行,輸出了當前是誰登錄了系統,而后運行了whoami,輸出的是當前有效用戶名,使用這個方式可以運行多個命令,他們都是以此串行的,
二、構建一個shell檔案
構建一個shell檔案,最簡單的理解就是將類似上述的命令放在一個文本檔案里,文本檔案的核心開頭是:
#!/bin/bash
#內容解釋:
在通常的shell腳本中,井號(#)用作注釋行,shell并不會處理shell腳本中的注釋行,而, shell腳本檔案的第一行是個例外,#后面的驚嘆號會告訴shell用哪個shell來運行腳本
該行內容必須放在文本的第一行,表示使用的shell型別;本文以常用的bash為例,更多了型別的shell可以參考此文,
在第一行的內容后面,就可以寫入你要執行的shell命令了,可以都寫在一行,用分號隔開,但是一般情況下,為了美觀和更高的辨識度,我們選擇一行寫一個命令,加上一個回車符,在輸入另一個命令,好比下圖:

推薦格式:
需要說明的是,你可以在文本中用"#"來注釋你的內容,這樣這些被注釋的內容,shell就不會識別和執行了,一般我們會在腳本中寫一些說明性的描述,這時需要用到"#",如下圖:

上述可以是一個完整的shell腳本了,可以直接保存為腳本檔案test1,但是此時我們如果直接執行test1檔案的話,還是不能達到效果的,會提示 command not found,這里就需要提到shell里的PATH環境變數的概念,shell 命令的查找都是通過環境變數的,

我們可以查看當前主機的環境變數:

此時我們的test1命令并沒有生效,如果我們想要使其神效,可以采用這兩個方式:
- 將shell腳本檔案所處的目錄添加到PATH環境變數中;
- 在提示符中用絕對或相對檔案路徑來參考shell腳本檔案;
經驗提示:
在centos Linux 發行版中,有的會將 $HOME/bin 目錄添加進了 PATH 環境變數,它在每個用戶的 HOME 目錄下提供了一個存放檔案的地方,shell 可以在那里查找要執行的命令;
核心說明:
執行時我們會發現還是沒有執行成功,此時可以看到終端列印了 " Permission denied",這報錯大家一定要熟悉起來,因為在以后的作業中,我們可能會遇到很多這種報錯,遇到這個問題我們的第一反應就應該是想到,有些檔案或者目錄,我們當前的用戶是沒有相關的權限導致,正如test1檔案,我們當前的test1用戶是沒有執行權限的,所以我們需要做的就是使用chmod 給檔案添加對應的權限,
chmod u+x test1 添加權限后:

此時腳本檔案就可以正常執行了,

實戰解說:
作業中我們創建的腳本檔案,一般都是用.sh 結尾的,這個是給我們電腦的使用者來識別用的,這樣我們就可以一眼識別這個檔案就是一個shell 腳本檔案,比如上面的test1檔案,我們通常是命名為test1.sh的,而且執行這個檔案的時候,我們可以有一個更簡單的方式,腳本對應的sh或bash來執行,好比上面的./test1 我們可以更換為 bash test1,會有同樣的效果,

三、終端列印訊息
很多時候shell都會輸出一定的內容到終端,我們如果也想在腳本中輸出一些內容到終端顯示,告訴執行腳本的人,這個腳本在執行哪些功能,這個時候我們就需要用到echo命令來輔助,
最簡單的輸出如下:

echo 命令會將跟在它后面的字串列印到終端螢屏,
此時我們如果想要引號也輸出在終端的話,需要這樣做:echo "Let's see if this'll work"

核心總結:
echo 命令可用單引號或雙引號來劃定文本字串,如果在字串中用到了它們,你需要在文本中使用其中一種引號,而用另外一種來將字串劃定起來,
此時我們就可以在腳本檔案中任意位置使用echo來輸出我們打算輸出的內容了,如下圖:

常用的組合命令引數:
- -n 不換行輸出

- -e 處理特殊字符
\a 發出警告聲;
\b 洗掉前一個字符;
\c 最后不加上換行符號;
\f 換行但游標仍舊停留在原來的位置;
\n 換行且游標移至行首;
\r 游標移至行首,但不換行;
\t 插入tab;
\v 與\f相同;
\ 插入\字符;
\nnn 插入nnn(八進制)所代表的ASCII字符;

實戰解說:
在實際的使用中,我們通常也會使用echo 配合>>將內容追加到文本檔案中,如下圖:

四、變數的使用
有些時候我們會需要在 shell 命令使用 其他資料來處理資訊,這可以通過變數來實作,變數允許臨時性地將資訊存盤在shell 腳本中, 以便和腳本中的其他命令一起使用,
4.1 環境變數
shell維護著一組環境變數,用來記錄特定的系統資訊,比如系統的名稱、登錄到系統上的用 戶名、用戶的系統ID (也稱為 UID )、用戶的默認主目錄以及 shell 查找程式的搜索徑,可以用 set命令來顯示一份完整的當前環境變數串列,
【...】
在腳本中,變數的使用格式是:$變數名稱
下面是變數在腳本中的使用,可以看到

實戰解說:
如上文中的$HOME,我們一般還可以寫成${HOME} 這兩者的效果是等同的,而且需要注意的是,我們在$符號之前不能只是\,這樣變數就會失效了,另一個需要注意的是,當你的變數需要和一個字串連用的時候,此時一定要用{}的形式,否則變數會失效,如下圖演示:
變數用{}包括起來:
4.2 用戶變數
除了環境變數, shell 腳本還允許在腳本中定義和使用自己的變數,定義變數允許臨時存盤數據并在整個腳本中使用,從而使 shell 腳本看起來更像一個真正的計算機程式,用戶變數可以是任何由字母、數字或下劃線組成的文本字串,長度不超過 20 個,用戶變數區分大小寫,所以變數 Var1 和變數 var1 是不同的,這個小規矩經常讓腳本編程初學者感到頭疼,使用等號將值賦給用戶變數,在變數、等號和值之間不能出現空格(另一個困擾初學者的用法),這里有一些給用戶變數賦值的例子,
變數示例:
var1=10var2=-57var3=testingvar4="still more testing"
核心解說:
變數每次被參考時,都會輸出當前賦給它的值,需要記住的是,參考一個變數值時需要使 用$符,而參考變數來對其進行賦值時則不要使用美元符,看下面的例子,


4.3命令替換
shell 腳本中最有用的特性之一就是可以從命令輸出中提取資訊,并將其賦給變數,把輸出賦給變數之后,就可以隨意在腳本中使用了,這個特性在處理腳本資料時尤為方便,
兩種操作方式:
- 反引號字符(`)
- $()
核心解說:
需要注意反引號字符,這可不是用于字串的那個普通的單引號字符,由于在 shell 腳本之外很 少用到,你可能甚至都不知道在鍵盤什么地方能找到這個字符,但你必須慢慢熟悉它,因為這是 許多shell 腳本中的重要組件,提示:在美式鍵盤上,它通常和波浪線( ~ )位于同一鍵位, 命令替換允許你將shell 命令的輸出賦給變數,盡管這看起來并不那么重要,但它卻是腳本編 程中的一個主要組成部分,
實戰詳解:
命令替換會創建一個子 shell 來運行對應的命令,子 shell ( subshell )是由運行該腳本的 shell所創建出來的一個獨立的子 shell ( child shell ),正因如此,由該子 shell 所執行命令是無法使用腳本中所創建的變數的,在命令列提示符下使用路徑 ./ 運行命令的話,也會創建出子 shell ;要是運行命令的時候 不加入路徑,就不會創建子shell ,如果你使用的是內建的 shell 命令,并不會涉及子 shell , 在命令列提示符下運行腳本時一定要留心!
五、重定向輸入和輸出
很多時候想要保存某個命令的輸出而不僅僅只是讓它顯示在顯示幕上, bash shell 提供了幾 個運算子,可以將命令的輸出重定向到另一個位置(比如檔案),重定向可以用于輸入,也可以 用于輸出,可以將檔案重定向到命令輸入,
5.1 輸出重定向
command > outputfile

可以看到,who命令產生的內容并沒有覆寫1.txt中已有的內容,而是追加到檔案的末尾,
5.2 輸入重定向
command < inputfile
- 文本的行數
- 文本的詞數
- 文本的位元組數
六、管道
通過前面的學習,我們已經知道了怎樣從檔案重定向輸入,以及重定向輸出到檔案,Shell 還有一種功能,就是可以將兩個或者多個命令(程式或者行程)連接到一起,把一個命令的輸出作為下一個命令的輸入,以這種方式連接的兩個或者多個命令就形成了管道 ‘|’(pipe),
Linux 管道使用豎線|連接多個命令,這被稱為管道符,Linux 管道的具體語法格式如下:
command1 | command2
command1 | command2 [ | commandN... ]
當在兩個命令之間設定管道時,管道符
|左邊命令的輸出就變成了右邊命令的輸入,只要第一個命令向標準輸出寫入,而第二個命令是從標準輸入讀取,那么這兩個命令就可以形成一個管道,大部分的 Linux 命令都可以用來形成管道,
核心講解:
這里需要注意,command1 必須有正確輸出,而 command2 必須可以處理 command2 的輸出結果;而且 command2 只能處理 command1 的正確輸出結果,不能處理 command1 的錯誤資訊,
使用示例:
a.作業中常用的就是配合grep 使用,下圖表示的意思是,將cat讀取出來的文本內容發送到 grep 命令;

b.使用管道將 cat 命令的輸出作為 less 命令的輸入,這樣就可以將 cat 命令的輸出每次按照一個螢屏的長度顯示,這對于查看長度大于一個螢屏的檔案內容很有幫助,

c.查看指定程式的行程運行狀態,并將輸出重定向到檔案中,
d.統計系統中當前登錄的用戶數,

七、執行數學運算
對任何編程語言都很重要的特性是運算元字的能力,遺憾的是,對 shell 腳本來說,這個處理程序會比較麻煩,在 shell 腳本中有兩種途徑來進行數學運算,
7.1 expr 命令
expr 對運算式的格式有幾點特殊的要求:
- 出現在
運算式中的運算子、數字、變數和小括號的左右兩邊至少要有一個空格,否則會報錯, - 有些特殊符號必須用反斜杠
\進行轉義(屏蔽其特殊含義),比如乘號*和小括號(),如果不用\轉義,那么 Shell 會把它們誤解為正則運算式中的符號(*對應通配符,()對應分組), - 使用變數時要加
$前綴,
[root@bd15-21-131-161 ~]# expr 2 +3 #錯誤:加號和 3 之前沒有空格
expr: syntax error
[root@bd15-21-131-161 ~]# expr 2 + 3 #這樣才是正確的
5
[root@bd15-21-131-161 ~]# expr 4 * 5 #錯誤:乘號沒有轉義
expr: syntax error
[root@bd15-21-131-161 ~]# expr 4 \* 5 #使用 \ 轉義后才是正確的
20
[root@bd15-21-131-161 ~]# expr ( 2 + 3 ) \* 4 #小括號也需要轉義
-bash: syntax error near unexpected token `2'
[root@bd15-21-131-161 ~]# expr \( 2 + 3 \) \* 4 #使用 \ 轉義后才是正確的
20
[root@bd15-21-131-161 ~]# n=3
[root@bd15-21-131-161 ~]# expr n + 2
expr: non-numeric argument
[root@bd15-21-131-161 ~]# expr $n + 2 #使用變數時要加 $
5
[root@bd15-21-131-161 ~]# m=7
[root@bd15-21-131-161 ~]# expr $m \* \( $n + 5 \)
56
以上是直接使用 expr 命令,計算結果會直接輸出,如果你希望將計算結果賦值給變數,那么需要將整個運算式用反引號``(位于 Tab 鍵的上方)包圍起來,請看下面的例子,

實戰詳解:
使用 expr 進行數學計算是多么的麻煩呀,需要注意各種細節,作業中不推薦使用,
7.2 使用方括號[ ]
bash shell 為了保持跟 Bourne shell 的兼容而包含了 expr 命令,但它同樣也提供了一種更簡單的方法來執行數學運算式,在bash 中,在將一個數學運算結果賦給某個變數時,可以用美元符和 方括號($[ operation ] )將數學運算式圍起來.

用方括號執行shell數學運算比用expr命令方便很多,這種技術也適用于shell腳本,

需要額外注意的是bash shell數學運算子只支持整數運算,若要進行任何實際的數學計算,這是一個巨大的限制,如下圖:
八、退出腳本
迄今為止所有的示例腳本中,我們都是突然停下來的,運行完最后一條命令時,腳本就結束了,其實還有另外一種更優雅的方法可以為腳本劃上一個句號,shell 中運行的每個命令都使用 退出狀態碼 ( exit status )告訴 shell 它已經運行完畢,退出狀態碼是一個 0 ~ 255 的整數值,在命令結束運行時由命令傳給 shell ,可以捕獲這個值并在腳本中使用,
8.1 查看退出狀態碼
Linux 提供了一個專門的變數 $? 來保存上個已執行命令的退出狀態碼,對于需要進行檢查的命令,必須在其運行完畢后立刻查看或使用$? 變數,它的值會變成由 shell 所執行的最后一條命令 的退出狀態碼,

如果命令成功結束,那么它退出的狀態碼就是 0,如果是失敗的,那狀態碼就是一個非零的正數值,

退出狀態碼126表明用戶沒有執行命令的正確權限,
另一個會碰到的常見錯誤是給某個命令提供了無效引數,

8.2 exit
exit 是一個 Shell 內置命令,用來退出當前 Shell 行程,并回傳一個退出狀態;使用
$?可以接收這個退出狀態,exit 命令可以接受一個整數值作為引數,代表退出狀態,如果不指定,默認狀態值是 0,
一般情況下,退出狀態為 0 表示成功,退出狀態為非 0 表示執行失敗(出錯)了,
exit 退出狀態只能是一個介于 0~255 之間的整數,其中只有 0 表示成功,其它值都表示失敗,
Shell 行程執行出錯時,可以根據退出狀態來判斷具體出現了什么錯誤,比如打開一個檔案時,我們可以指定 1 表示檔案不存在,2 表示檔案沒有讀取權限,3 表示檔案型別不對,

可以看到,"after exit"并沒有輸出,這說明遇到 exit 命令后,test1執行就結束了,
實戰詳解:
注意,exit 表示退出當前 Shell 行程,我們必須在新行程中運行 test1,否則當前 Shell 會話(終端視窗)會被關閉,我們就無法看到輸出結果了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/303087.html
標籤:其他
下一篇:??《不知道密碼也能登錄Linux系統管理員賬號!!!》??——再也不用擔心忘記Linux系統密碼了, GRUB啟動作業系統教程!(建議收藏)
