Shell中傻傻分不清楚的TOP3
阿新 • • 發佈:2020-06-05
Shell中傻傻分不清楚的TOP3
釋出文章
![](https://upload-images.jianshu.io/upload_images/10998555-3934f6a15aa3da5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
近來小姐姐又犯憨憨錯誤,問組內小夥伴`export`命令不會持久化環境變數嗎?反正我是問出口了。。然後小夥伴就甩給了我一個《The Linux Command Line》PDF連結。感謝老大不殺之恩~
Shell是命令直譯器,它會接受使用者輸入的各種命令,並傳遞給作業系統執行。它的作用類似於Windows系統的命令列。在UNIX或Linux系統中,Shell即是使用者互動的介面,也是控制系統的指令碼語言。當然現在使用者也可以選擇圖形化介面做一些和作業系統的互動。層次示意圖如下:
![](https://upload-images.jianshu.io/upload_images/10998555-1b028566ea67ad4b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
對於初學者來說,可能搞不清楚Shell怎麼會有那麼多分類,Shell的語法怎麼那麼隨便...
小姐姐結合自己初學Shell傻傻分不清的問題點,主要從`Shell的種類`,`變數的分類`,`條件測試的表達`三個部分來介紹。
>### Shell的種類
shell程式有**sh**,**bash**,**zsh**等分類,我從網上找到一張圖可以看出shell程式的發展史。
![](https://upload-images.jianshu.io/upload_images/10998555-41099056ee40fa48.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
對於這些Shell程式,其語法或多或少有一些差異,不過我們通常使用的都是bash。
* Shell程式資訊
在Linux系統我們可以通過一些命令檢視或修改當前Shell程式資訊。
![](https://upload-images.jianshu.io/upload_images/10998555-b45b7a79c07f2d58.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
一般發行版的Linux系統中,預設的shell程式就是bash。我們在寫shell指令碼時,通常也會在指令碼檔案頭部指定bash作為指令碼直譯器。
![](https://upload-images.jianshu.io/upload_images/10998555-9fea6721008d778d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
這裡多說一句,zsh有時也作為猿媛們的預設shell。zsh語法大多是和bash匹配的,也不會影響shell指令碼的執行(因為指令碼頭部指定bash就還是bash:),也不會影響像小姐姐這樣的渣渣使用。用它是因為它有神奇的開源框架 Oh My God.. 哦不,是 **Oh My Zsh** !!!
後面的內容我們還是以Linux系統中的bash為例來介紹:)
>### 變數的分類
Shell是一門動態型別語言和弱型別語言,我們可以把變數理解為KV對,key是變數名,value是變數值。變數大體可以分為`環境變數`,`系統變數`,`使用者定義的變數`三類。
* 環境變數
比如我們經常配置的`JAVA_HOME`就屬於環境變數,這些變數是所有Shell程式執行時都可以使用的變數。關於環境變數的操作命令舉例如下:
![](https://upload-images.jianshu.io/upload_images/10998555-8082e3dda8d6b25c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://upload-images.jianshu.io/upload_images/10998555-315ec87369467feb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用`export`命令定義的環境變數只在當前執行的shell程序中有效,結束程序就沒了。所以我們要將配置變數定義在令小姐姐懵逼的一系列配置檔案中,持久化下來。
說起配置檔案,又不得不先提下shell程式和使用者的Interactive和Login模式:)
* Interactive & Non-Interactive`
`Interactive`通常是指讀入寫出資料都是從使用者的terminal,也就是我們平時用命令列開啟終端就是Interactive模式,而執行一個shell指令碼就是`Non-interactive`模式。怎麼檢驗當前shell執行的模式是不是Interactive呢?小姐姐從GNU網站拷貝了一段裝X指令碼:
```
case "$-" in
*i*) echo This shell is interactive ;;
*) echo This shell is not interactive ;;
esac
```
結果如上所述。
* Login & Non-Login`
Login模式指的是使用者成功登入後開啟的shell程序,這時候會讀取`/etc/passwd`下使用者所屬的shell去執行。
![](https://upload-images.jianshu.io/upload_images/10998555-c9e0a2e670e1e45c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Non-login模式指的是非登入使用者狀態下開啟的shell程序,我們可以通過`echo $0`區分。
![](https://upload-images.jianshu.io/upload_images/10998555-399bcf9c2daca9ca.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
扯這麼多是因為配置檔案的載入順序和shell程序是否執行在Interactive和Login模式有關係:D
![](https://upload-images.jianshu.io/upload_images/10998555-157466e35feea5d8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
這是阿姨從網上粘的圖。bash支援的配置檔案有/etc/profile,~/.bashrc等。
當呼叫一個**Interactive&Login**模式的shell程序時,配置檔案的載入順序為:
`/etc/profile` —>`( ~/.bash_profile, ~/.bash_login, ~/.profile)其中之一` —>`~/.bash_loginout`(退出shell時呼叫)
當呼叫一個**Interactive&non-Login**模式的shell程序時,配置檔案的載入順序為:
`/etc/bash.bashrc` —>` ~/.bashrc`
當呼叫一個`non-nteractive`模式的shell程序時,通常是執行指令碼時,此時配置項是從環境變數中讀取和執行的,也就是`env`命令輸出的配置項。
另外,在開啟一個shell程序中,有一些引數的值也會影響到配置檔案的載入。如-