1. 程式人生 > >2017-11-27Linux基礎知識(14)bash特性之腳本編程初步

2017-11-27Linux基礎知識(14)bash特性之腳本編程初步

linux 基礎

回顧一下我們講述了用戶管理、權限管理以及還介紹了兩個命令,一個是install命令,另一個是mktemp,在這裏我們並不多做介紹。
對於用戶管理來說,是對權限的資源進行其隔離分配。
而對於權限來說,是對該系統的登錄用戶分配給資源所應有的權限。
那麽我們在這一章節當中來講述bash特性及bash腳本的初級編程。

一、bash是什麽

我們先來看一張圖用來解釋什麽是bash。

技術分享圖片

在這張圖中我們可以看到,最內部的是硬件,而後是內核,內核將硬件的復雜性和區別性給隱藏起來,輸出成一個統一而又簡潔的接口,我們就把它稱之為系統調用,在這個外層當中程序員使用該接口就可以無視底層硬件的復雜性,程序員通過系統調用接口來開發程序,但系統調用為了做的足夠的簡潔,所以它做的非常的底層,只是將復雜的硬件隱藏起來,而後又向外輸出,由於系統調用接口太過於底層,所以程序的開發周期會非常的長,而且維護起來也是極為不便的,不過在早期確實有很大的好處,因為要換取較好的性能,不過現在的計算機性能已經大幅度的提升,為了能讓程序開發的更快,即使有寫冗余的代碼也是無所謂的,所以在系統調用上有封裝了一個庫函數,使得開發程序可直接調用庫函數就可以,離人又更進了一步。

而終端是用戶交互的手段,是我們用戶最先接觸的一個東西,我們使用該終端間接控制內核,用戶是不能夠對內核進行操作的,因為在這個環節鏈條上,最薄弱的環節無非就是人類了,而終端的界面我們也稱之為shell界面,在之前的第三章我們講述了shell接口,分別是GUI和CLI,GUI在服務器當中並不常用,而CLI界面是文本界面,是服務器中必須要用它來對系統進行操作的,我們如何查看系統支持那些shell就在/etc/shells中查看。

   # cat /etc/shells 
   /bin/sh
   /bin/bash
   /sbin/nologin
   /usr/bin/sh
   /usr/bin/bash
   /usr/sbin/nologin

二、bash特性

除了我們之前講過的bash中的命令補全和命令行展開等,還有其它的特性,我們現在一一列舉bash特性:

   命令行展開:~, {}
   命令別名: alias, unalias
   命令歷史: history
   文件名通配:glob
   命令環境變量:$PATH
   快捷鍵:Ctrl+a, e, u, l
   路徑補全:

我們來說一下別名,別名是將原來的命令給隱藏起來,換成用戶人為的命令,它是一個shell內部命令,命令格式如下:

   alias [-p] [name[=value] ... ]

不過在shell中設置的,一退出終端就沒有了,所以我們可以寫在配置文件裏,例如:.bashrc退出終端後即可生效,不過這是個人,並不是全局設置。

2.1 bash特性之命令hash

我們此前說過命令在$PATH環境變量中查找的過程,我們在shell中輸入某個字符,shell會從$PATH中從左往右依次查找該命令,如果找到則停止查找,找不到shell也會提示相應的結果,hash命令就是將$PATH變量中查找到的命令給緩存下來,將命令的查找結果放到內存當中,這樣的話緩存下來的命令就不用在$PATH變量中進行查找了。其存儲的格式為:key-value。

   key:搜索鍵
   value:值

hash命令的選項有:

   hash:列出;
   hash -d COMMAND:刪除某個命令;
   hash -r:清空;

2.2 bash特性之變量

任何一種編程語言都有變量,程序是由指令加數據組成的,指令就是由程序文件來提供,而數據的提供是由IO、文件、管道和變量來提供,所以程序又可以稱之為算法加數據結構。
而變量的參與就是將文件的某個數據放入到內存中進行CPU指令運行或運算,其結果放入到另外一個內存中去,最後將其輸出出來。
變量也是提供數據的一種方式,它是內存運行申請的一塊空間,而變量名稱是內存運行空間的起始地址。所以變量名+指向的空間共同組成。變量的賦值方法我們之前也講過name=value。
變量的類型也有很多種,它是指值的存儲類型,根據其存儲格式(主要是數值還是字符)、表示的數據範圍以及參與的運算,主要圍繞這幾個而展開,定義的變量類型就定義了其存儲格式和其能夠參與的運算。而編程語言類型來講,根據類型的要求是否嚴格,我們大致分為其兩類,一種是強類型變量編程語言,不能有一點違反的規則,該是數值就是數值,先編譯後執行;另一種是弱類型變量編程語言,邊解釋邊執行。而shell就是弱類型的語言,因為bash把所有的變量統統視作為字符型。而且bash的變量無需事先聲明;相當於就是把聲明和賦值的過程同時實現。所以說通常變量的聲明也就是類型和變量名稱。
我們把變量名出現的地方轉換為數據地方叫做變量替換,換句話說是把變量名出現的位置替換為其所指向的內存中的數據,而這個就叫做變量替換。
那麽變量引用就是取得一個變量名所指向的在內存空間中的數據。例如${var_name}, $var_name。
變量名的命令規定為:變量名只能包含數字、字母和下劃線,但不能以數字開頭。而變量名的命名我們也要盡可能做到其見名知義,命名機制遵循某種法則;不能夠使用程序的保留字,例如:if, else, then, for等。

2.3 bash變量類型

這裏的bash的變量類型是指的它的作用域的變量類型,共有三類,分別是本地變量、環境變量和局部變量,還有位置參數變量以及特殊變量。總結如下:

   本地變量:作用域僅限為當前shell;
   環境變量:作用域為當前shell進程及其子shell進程;
   局部變量:作用域僅為某代碼片段(通常用於函數上下文當中);

   位置參數變量:向執行腳本的shell進程傳遞參數;
   特殊變量:shell內置的有特殊功用的變量;
	   例如:$?
	  	  0:成功
		  1-255:失敗

我們現在來看一下本地變量的使用方法,主要查看如何變量賦值和引用,以及查看變量和撤銷變量。

   變量賦值:name=value
   變量引用:${name}, $name
	   "":變量名會替換其值;
	   '':變量名不會替換為其值;
   查看變量:set
   撤銷變量:unset name
	   註意:此處非變量引用;

而環境變量的使用方法也是和本地變量也是基本相同的,不過在作用域上範圍比本地變量大一些。

   變量賦值:
	   (1) export name=value
	   (2) name=value
	     export name
	   (3) declare -x name=value
	   (4) name=value
	     declare -x name
	
	   註意:導出時不要在變量前加$,因為這是一種處理機制,而不是應用。
       變量引用:${name}, $name

   註意:bash內嵌了許多環境變量(通常為全大寫字符),用於定義bash的工作環境
	   PATH, HISTFILE, HISTFILESIZE, HISTCONTROL, SHELL, HOME, UID, PWD, OLDPWD等;

   查看環境變量:export, declare -x, printenv, env

我們還可以定義只讀變量,但只讀變量是無非重新賦值,並且也不支持撤銷;存活時間為當前shell進程的生命周期,說明它是隨著shell進程而終止的。

   (2) readonly name

2.4 bash特性之多命令執行

多命令執行是指在同一個命令行當中執行多條命令,如果你的命令沒有什麽邏輯關系,只是先後依次運行,用;分隔開即可;無論執行正確或錯誤,將所有的命令依次執行完成。

   # COMMAND1; COMMAND2; COMMAND3; ...

還有就是根據邏輯運算之間來進行多命令執行,根據布爾型來得到其結果,就是真或假。

   真(true, yes, on, 1)
   假(false, no, off, 0)

不過,對於命令的狀態返回結果來講,真表示為0,所以說邏輯的運算結果:0表示真。有以下邏輯表達運算方式,分別是與、或、非,那麽與就是乘法,除以任何數都等於0,非就是加法,1加上0等於1,而非就是取反。

   與:(乘法)
	   1 && 1 = 1
	   1 && 0 = 0
	   0 && 1 = 0
	   0 && 0 = 0
   或:(加法)
	   1 || 1 = 1
	   1 || 0 = 1
	   0 || 1 = 1
	   0 || 0 = 0
   非:
	   ! 1 = 0
	   ! 0 = 1

那麽我們說一下短路法則,我們以一下案例來說明:

   # COMMAND1 && COMMAND2

這個意思就是COMMAND1的執行結果如果為真,就必須執行COMMAND2;如果COMMAND1執行狀態結果為假時,則COMMAND2不會執行,這個我們稱之為串聯。

   # COMMAND1 || COMMAND2

這個就是COMMAND1執行狀態結果為真時,則COMMAND2不會被執行,但如果COMMAND1執行狀態結果為假時,COMMAND2就會被執行。這個我們稱之為並聯。
示例:

   id $username || useradd  $username


2017-11-27Linux基礎知識(14)bash特性之腳本編程初步