Shell中傻傻分不清楚的TOP3

monica2333發表於2020-06-04

Shell中傻傻分不清楚的TOP3
釋出文章

近來小姐姐又犯憨憨錯誤,問組內小夥伴export命令不會持久化環境變數嗎?反正我是問出口了。。然後小夥伴就甩給了我一個《The Linux Command Line》PDF連結。感謝老大不殺之恩~

Shell是命令直譯器,它會接受使用者輸入的各種命令,並傳遞給作業系統執行。它的作用類似於Windows系統的命令列。在UNIX或Linux系統中,Shell即是使用者互動的介面,也是控制系統的指令碼語言。當然現在使用者也可以選擇圖形化介面做一些和作業系統的互動。層次示意圖如下:

對於初學者來說,可能搞不清楚Shell怎麼會有那麼多分類,Shell的語法怎麼那麼隨便...

小姐姐結合自己初學Shell傻傻分不清的問題點,主要從Shell的種類,變數的分類,條件測試的表達三個部分來介紹。

Shell的種類

shell程式有shbash,zsh等分類,我從網上找到一張圖可以看出shell程式的發展史。

對於這些Shell程式,其語法或多或少有一些差異,不過我們通常使用的都是bash。

  • Shell程式資訊

在Linux系統我們可以通過一些命令檢視或修改當前Shell程式資訊。

一般發行版的Linux系統中,預設的shell程式就是bash。我們在寫shell指令碼時,通常也會在指令碼檔案頭部指定bash作為指令碼直譯器。

這裡多說一句,zsh有時也作為猿媛們的預設shell。zsh語法大多是和bash匹配的,也不會影響shell指令碼的執行(因為指令碼頭部指定bash就還是bash:),也不會影響像小姐姐這樣的渣渣使用。用它是因為它有神奇的開源框架 Oh My God.. 哦不,是 Oh My Zsh !!!

後面的內容我們還是以Linux系統中的bash為例來介紹:)

變數的分類

Shell是一門動態型別語言和弱型別語言,我們可以把變數理解為KV對,key是變數名,value是變數值。變數大體可以分為環境變數系統變數使用者定義的變數三類。

  • 環境變數

比如我們經常配置的JAVA_HOME就屬於環境變數,這些變數是所有Shell程式執行時都可以使用的變數。關於環境變數的操作命令舉例如下:

使用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去執行。

Non-login模式指的是非登入使用者狀態下開啟的shell程式,我們可以通過echo $0區分。

扯這麼多是因為配置檔案的載入順序和shell程式是否執行在Interactive和Login模式有關係:D


這是阿姨從網上粘的圖。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程式中,有一些引數的值也會影響到配置檔案的載入。如--rcfile ,--norc等。這些引數的含義值可以使用man bash進一步瞭解。只要保持預設值,其實就是我們上面介紹的配置檔案載入順序。

還有,在發行版的Linux系統中,Interactive&Login模式下的~/.bash_profile,
~/.bash_login, ~/.profile並不一定是三選一,看一下這三個指令碼的內容會發現他們會繼續呼叫下一個它想呼叫的配置檔案,這樣就可以避免配置項可能需要在不同的配置檔案多次配置的弊端了。如centos7.2 中 ~/.bash_profile檔案中實際呼叫了 ~/.bashrc檔案。

按照模式和引數設定啟動的shell程式的配置檔案載入流程圖如下:

好了,到目前我們總算把環境變數中配置檔案的載入順序理清了。下面列舉一些常用的Shell環境變數吧。

  • 系統變數
    Shell中系統變數主要在對引數判斷和命令返回值判斷時使用,包括指令碼和函式的引數和返回值判斷。沒啥可說的,主要難記且指令碼中經常出現:

  • 使用者自定義的變數
    是指我們在使用命令或指令碼時定義的變數,因為shell是弱型別語言且語法XX,這裡主要談談初學時的幾個坑爹點:

  • “=” 左右兩邊不能有空格

    你懂我說的意思了吧。。

  • 引用
    所謂引用,指的是將字串用引用符號包括起來,以防止其中的特殊符號被Shell解釋為其他涵義。

常用的引用符號如下:

  • $

前面我們其實一直在用 “ $變數名 ” 來表示某個 變數名的值,這其實也正是 $ 的作用。

  • shell中變數名的大小寫是敏感的

好了就這麼多吧。

條件測試的表達

shell指令碼中除了變數,還經常出現的語法就是條件測試的判斷。不會寫指令碼的開發小姐姐不是好運維,我們來一起侃侃吧。

  • 基本語法

在Shell程式中,當指定的條件為真時,整個條件測試的返回值為 0;反之,如果指定的條件為假時,整個條件測試的返回值為 非0。

條件測試表示式的書寫有test expression[ expression ]兩種形式,注意後者的空格一定不能省!!

指令碼中經常出現的有字串測試、整數測試、檔案測試、邏輯操作符測試。我們一起看下:)

  • 字串測試

注意:這裡運算子 左右兩邊又一定要有空格了(下同),這樣shell才能將之當成命令執行。

  • 整數測試

  • 檔案測試

邏輯操作符測試

收藏在看轉發起來,小姐姐就算你條件測試過關了>_<

感謝大佬這麼優秀還關注我~

參考資料:
[1].《Shell從入門到精通》
[2].https://www.edureka.co/blog/types-of-shells-in-linux/
[3].http://www.penguintutor.com/linux/basic-shell-reference
[4].https://apple.stackexchange.com/questions/361870/what-are-the-practical-differences-between-bash-and-zsh
[5].https://sunlightmedia.org/bash-vs-zsh/
[6].https://unix.stackexchange.com/questions/439042/debian-read-order-of-bash-session-configuration-files-inconsistent
[7].https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
[8].http://howtolamp.com/articles/difference-between-login-and-non-login-shell/
[9].https://shreevatsa.wordpress.com/2008/03/30/zshbash-startup-files-loading-order-bashrc-zshrc-etc/

Shell中傻傻分不清楚的TOP3
同步滾動:

近來小姐姐又犯憨憨錯誤,問組內小夥伴export命令不會持久化環境變數嗎?反正我是問出口了。。然後小夥伴就甩給了我一個《The Linux Command Line》PDF連結。感謝老大不殺之恩~

Shell是命令直譯器,它會接受使用者輸入的各種命令,並傳遞給作業系統執行。它的作用類似於Windows系統的命令列。在UNIX或Linux系統中,Shell即是使用者互動的介面,也是控制系統的指令碼語言。當然現在使用者也可以選擇圖形化介面做一些和作業系統的互動。層次示意圖如下:

對於初學者來說,可能搞不清楚Shell怎麼會有那麼多分類,Shell的語法怎麼那麼隨便...

小姐姐結合自己初學Shell傻傻分不清的問題點,主要從Shell的種類,變數的分類,條件測試的表達三個部分來介紹。

Shell的種類
shell程式有sh,bash,zsh等分類,我從網上找到一張圖可以看出shell程式的發展史。

對於這些Shell程式,其語法或多或少有一些差異,不過我們通常使用的都是bash。
Shell程式資訊
在Linux系統我們可以通過一些命令檢視或修改當前Shell程式資訊。

一般發行版的Linux系統中,預設的shell程式就是bash。我們在寫shell指令碼時,通常也會在指令碼檔案頭部指定bash作為指令碼直譯器。

這裡多說一句,zsh有時也作為猿媛們的預設shell。zsh語法大多是和bash匹配的,也不會影響shell指令碼的執行(因為指令碼頭部指定bash就還是bash:),也不會影響像小姐姐這樣的渣渣使用。用它是因為它有神奇的開源框架 Oh My God.. 哦不,是 Oh My Zsh !!!

後面的內容我們還是以Linux系統中的bash為例來介紹:)

變數的分類
Shell是一門動態型別語言和弱型別語言,我們可以把變數理解為KV對,key是變數名,value是變數值。變數大體可以分為環境變數,系統變數,使用者定義的變數三類。

環境變數
比如我們經常配置的JAVA_HOME就屬於環境變數,這些變數是所有Shell程式執行時都可以使用的變數。關於環境變數的操作命令舉例如下:

使用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去執行。

Non-login模式指的是非登入使用者狀態下開啟的shell程式,我們可以通過echo $0區分。

扯這麼多是因為配置檔案的載入順序和shell程式是否執行在Interactive和Login模式有關係:D

這是阿姨從網上粘的圖。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程式中,有一些引數的值也會影響到配置檔案的載入。如--rcfile ,--norc等。這些引數的含義值可以使用man bash進一步瞭解。只要保持預設值,其實就是我們上面介紹的配置檔案載入順序。

還有,在發行版的Linux系統中,Interactive&Login模式下的~/.bash_profile,
~/.bash_login, ~/.profile並不一定是三選一,看一下這三個指令碼的內容會發現他們會繼續呼叫下一個它想呼叫的配置檔案,這樣就可以避免配置項可能需要在不同的配置檔案多次配置的弊端了。如centos7.2 中 ~/.bash_profile檔案中實際呼叫了 ~/.bashrc檔案。

按照模式和引數設定啟動的shell程式的配置檔案載入流程圖如下:

好了,到目前我們總算把環境變數中配置檔案的載入順序理清了。下面列舉一些常用的Shell環境變數吧。

系統變數
Shell中系統變數主要在對引數判斷和命令返回值判斷時使用,包括指令碼和函式的引數和返回值判斷。沒啥可說的,主要難記且指令碼中經常出現:

使用者自定義的變數
是指我們在使用命令或指令碼時定義的變數,因為shell是弱型別語言且語法XX,這裡主要談談初學時的幾個坑爹點:

“=” 左右兩邊不能有空格

你懂我說的意思了吧。。

引用
所謂引用,指的是將字串用引用符號包括起來,以防止其中的特殊符號被Shell解釋為其他涵義。

常用的引用符號如下:

$
前面我們其實一直在用 “ 變數名 ” 來表示某個 變數名的值,這其實也正是 的作用。

shell中變數名的大小寫是敏感的
好了就這麼多吧。

條件測試的表達
shell指令碼中除了變數,還經常出現的語法就是條件測試的判斷。不會寫指令碼的開發小姐姐不是好運維,我們來一起侃侃吧。

基本語法
在Shell程式中,當指定的條件為真時,整個條件測試的返回值為 0;反之,如果指定的條件為假時,整個條件測試的返回值為 非0。

條件測試表示式的書寫有test expression 和 [ expression ]兩種形式,注意後者的空格一定不能省!!

指令碼中經常出現的有字串測試、整數測試、檔案測試、邏輯操作符測試。我們一起看下:)

字串測試

注意:這裡運算子 左右兩邊又一定要有空格了(下同),這樣shell才能將之當成命令執行。

整數測試

檔案測試

邏輯操作符測試

收藏在看轉發起來,小姐姐就算你條件測試過關了>_<

感謝大佬這麼優秀還關注我~

參考資料:
[1].《Shell從入門到精通》
[2].https://www.edureka.co/blog/types-of-shells-in-linux/
[3].http://www.penguintutor.com/linux/basic-shell-reference
[4].https://apple.stackexchange.com/questions/361870/what-are-the-practical-differences-between-bash-and-zsh
[5].https://sunlightmedia.org/bash-vs-zsh/
[6].https://unix.stackexchange.com/questions/439042/debian-read-order-of-bash-session-configuration-files-inconsistent
[7].https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
[8].http://howtolamp.com/articles/difference-between-login-and-non-login-shell/
[9].https://shreevatsa.wordpress.com/2008/03/30/zshbash-startup-files-loading-order-bashrc-zshrc-etc/

相關文章