1. 程式人生 > >Linux真小白入門教程第十集——詳探shell

Linux真小白入門教程第十集——詳探shell

shell不單單是一個CLI,它是一個時刻執行著的複雜互動式 程式它本身就是一個程序,那麼學習shell程序就顯得尤為必要。

系統啟動的shell程式型別取決於你的個人使用者ID配置,不過一般預設的都是bash shell

預設的互動式shell會在使用者登入某個虛擬控制檯終端或在GUI中執行終端模擬器時啟動。還有一個在/bin/sh下的shell,他作為預設的系統shell,用於那些需要在啟動時使用的系統shell指令碼。(兩個不一樣aaaaa)

預設的系統shell和預設的互動式shell有時並不相同。(首行語法要求,以規避兩種預設shell的麻煩

想要啟動其他的shell,可以直接輸入

/bin/dash

啟動dash shell

exit (同樣可巢狀退出shell)

直接退出dash shell

 

作為一個程序,shell同樣也有父子關係,預設的互動式shell,是一個父shell

如果在CLI中輸入/bin/bash 或者其他等效的bash指令,就會建立一個新的shell程式,這個shell程式就被稱為子shell,子shell也有CLI命令提示符,同樣等待命令的輸入。

從上圖可看出,下面的bash shell程序的父程序即為上一個bash程序

ps -forest可展示這些子shell的巢狀結構

 

除了使用bash shell命令或是執行shell指令碼,還可以使用程序列表的方式生成子shell

可以使用分號將命令分隔開來,所有的命令會依次執行命令列表想要成為程序列表,只要將這些命令包含在括號裡即可

括號的加入使得其生成程序列表,會生成了一個子shell來執行對應的命令

程序列表就是一個命令分組,另一種命令分組是將命令放入花括號{},並在命令列表尾部加上分號;{command;}

但這並不會創建出子shell來執行

若想知道是否生成了子shell,使用命令echo $BASH_SUBSHELL,如果返回0,就表明沒有子shell。

在shell指令碼中,經常使用子shell進行多程序處理

但是採用子shell的成本不菲,會拖慢處理速度。所以在CLI shell中,它並非真正的多程序處理,因為終端始終控制著子shell的IO。

 

在互動式shell中,一個高效的子shell用法是使用後臺模式,創建出有實用價值的子shell

後臺模式:在後臺模式中執行命令可以在處理命令的同時讓出CLI,以供他用。

sleep命令經常用來演示後臺模式,sleep接受一個引數,表示希望程序等待的秒數。這個命令經常在指令碼中用於引入一段時間的暫停。

sleep 10

將回話暫停10s

sleep 100&

後面加上字元&,會將命令置入後臺模式

當被置入後臺時,在shell CLI提示符返回之前,會出現兩條資訊。第一條資訊是顯示在方括號中的後臺作業號,第二條是後臺作業的程序ID

在下面的ps命令結果中,可以看到sleep 3000已經列出。

除了ps命令,你也可以使用jobs命令來顯示後臺作業資訊。

注意:後臺完成的作業,可能會突然出現哦~

 

程序列表是執行在子shell中的一條或者多條命令。將程序列表放入到後臺模式,既可以在子shell中進行繁複的處理工作,同時也不會讓子shell的IO受制於終端。

使用tar建立備份檔案是有效利用後臺程序列表的一個例子

(tar -cf Rich.tar /home/rich; tar -cf My.tar /home/chis)&

 

Linux中的協程,協程可以同時做兩件事:在後臺生成一個子shell,並在這個子shell中執行命令

要進行協程處理,需要使用coproc命令,還有要在子shell中執行的命令

(建立子shell,將命令置入後臺模式)啟動了後臺作業後,螢幕上顯示出了後臺作業號以及程序ID

還可以使用擴充套件命名發給協程取名字My_Job(在擁有多個協程時,以及想要跟他們通訊,需要自己命名)

注意命令中的空格

 

協程與程序相互結合,建立巢狀子shell

但是要記住建立子shell的成本不低,速度還慢,巢狀的子shell更加火上澆油。

 

理解shell內建命令

外部命令:也成為檔案系統命令,存在於bash shell之外的程式,它並不是shell程式的一部分,外部命令程式通常位於/bin /user/bin /sbin /usr/sbin中

ps就是一個外部命令,可以用which或type命令找到它的位置

當外部命令執行時,Linux會創建出一個子程序,這個過程被叫做forking,外部命令ps很方便顯示出它的父程序以及自己所對應的fork子程序

外部命令需要建立程序以及設定環境,所以需要一定的代價。(可以通過訊號進行通訊)

 

內建命令和外部命令的區別在於前者不需要建立子程序來執行,內建命令已經和shell編譯成了一體,作為shell工具的組成部分存在,不需要藉助外部程式檔案來執行(使用type命令可以顯示某個命令是否是內建的)

因為既不需要衍生出子程序來執行,也不需要開啟程式檔案,內建命令的執行速度要更快,效率也更高

但是也要注意有些命令既有外部命令也有內建命令(echo pwd)

使用type的-a選項可以看出,而which命令只顯示出外部命令檔案。

(直接輸入/bin/pwd,可直接執行外部的pwd命令)

 

比較有用的內建命令:

history命令會檢視到最近使用過的命令列表(修改HISTSIZE的環境變數可以設定儲存的命令數)

輸入!和編號,也可以執行之前的那條命令:

輸入!!,也可以召喚出剛才剛剛用過的那條命令並執行

bash命令的歷史記錄都是放在記憶體中的,當shell退出時才被寫入到歷史檔案(.bash_binary)中,若想強制寫入,history -a 即可完成。

 

alias命令也是一個內建命令,允許為經常用的命令建立另一個名稱

alias -p即可檢視到Linux設定好的一些命令或者引數的別名

等號加上單引號即可完成重新命名,隨時可以在shell中使用它,就算在shell指令碼中也可以使用,但是這個別名僅在它所被定義的shell程序中才有效,在其他的子shell中會失效