Shell就是一個指令行解釋器,它的作用是解釋執行使用者的指令,使用者輸入一條指令,Shell就解釋執行一條,這種方式稱為互動式(Interactive)。
Shell還有一種執行指令的方式稱為批處理(Batch),使用者事先寫一 個Shell腳本(Script),其中有很多條指令,讓Shell一次把這些指令執行完,而不必一條一條地敲 指令。Shell腳本和程式設計語言很相似,也有變量和流程控制語句,包括循環和分支。但Shell腳本是解釋執行的,不需 要編譯,Shell程式從腳本中一行一行讀取并執行這些指令,相當于一個使用者把腳本中的指令一行一 行敲到Shell提示符下執行。作為程式設計語言,它雖然不是 Linux系統核心的一部分,但它調用了系統核心的大部分功能來執行程式、建立文檔并以并行的方式協調各個程式的運作。
Unix系統中常見的shell有:sh、csh、ksh、tcsh、bash
使用指令: vim /etc/shells 可以檢視目前系統支援的bash
shell執行腳本
shell執行腳本是一門解釋性語言、批量化處理語言,大大的節省了工作成本
shell腳本第一行必須以 #!開頭,它表示該腳本使用後面的解釋器解釋執行。
舉個栗子:
//script.sh 注:這是一個文本檔案
1
2
3
4
5
!/bin/bash
echo “this is a test”
ls
ls -l
echo “there are all files”
執行方式:
1
2
3
4
5
6
//第一種執行方式:
[[email protected] Shell] chmod+xscript.sh[admin@localhostShell] ./script.sh
//第二種執行方式:
[[email protected] Shell]$ /bin/bash script.sh
執行過程:
Shell會fork一個子程序并調用exec執行./script.sh這個程式,exec系統調用應該把子程序的代碼段替換成./script.sh程式的代碼段,并從它的_start開始執行。然而script.sh是個文本檔案,根 本沒有代碼段和_start函數,怎麼辦呢?其實exec還有另外一種機制,如果要執行的是一個文本檔案,并且第一行 指定了解釋器,則用解釋器程式的代碼段替換目前程序,并且從解釋器 的_start開始執行,而這個文本檔案被當作指令行參數傳給解釋器。是以,執行上述腳本相當于執行程式!
輸入指令執行shell腳本後:
互動式程序(父程序)建立一個子程序用于執行腳本,父程序等待子程序終止
子程序程式替換bash解釋器
讀取shell腳本的指令,将其以參數傳遞的方式傳遞給bash解釋器
子bash對shell腳本傳入的參數進行讀取,讀一行識别到它是一個指令,則再建立一個子程序,子bash等待該新程序終止
新程序執行該指令,執行完後将結果交給子程序
子程序繼續讀取指令,建立新程序,新程序執行該指令,将結果傳回給子程序,直到執行完最後一條指令
子程序終止,将結果傳回給互動式父程序
注意:像export、cd、env、set 這些内置指令,在鍵入指令行後,互動式程序不會建立子程序,而是調用bash内部的函數執行這些指令,改變的是互動式程序。
如果在指令行下,将多個指令用括号括起來,并用分号隔開來執行,互動式程序依然會建立一個子shell執行括号中的指令:
如果不加括号則是另一種情況,cd .. 指令會直接在互動式shell下執行:
. 或者 source這兩個指令是Shell的内建指令,這種方式不會建立子Shell,而是直接在互動式Shell下逐行 執行腳本中的指令。
例證:
script.sh
1
2
3
4
5
!/bin/bash
ls
echo “#################”
cd ..
ls
shell變量
shell變量不需要進行任何聲明,直接定義即可,因為shell變量的值實際上都是字元串(對于沒有定義的變量預設是一個空串)。定義的時候shell變量由大寫字母加下劃線組成,并且定義的時候等号兩邊不能存在空格,否則會被認為是指令!
shell變量的種類:
環境變量:shell程序的環境變量可以從目前shell程序傳給fork出來的子程序。
本地變量:隻存在于目前shell程序
利用printenv可以顯示目前shell程序的環境變量;利用set指令可以顯示目前shell程序中的定義的所有變量(包括環境變量和本地變量)和函數。
一個shell變量定義後僅存在于目前Shell程序,是一個本地變量。用export指令可以把本地變量導出為環境變量。用unset指令可以删除已定義的環境變量或本地變量。
例如:
1
2
3
4
5
6
7
8
9
//分步 先定義後導出
COUNT=5
export COUNT
//一步完成定義和導出環境變量
export COUNT=5
//删除已經定義的環境變量
unset COUNT
變量引用:
引用shell變量要用到$符号,加{}可以防止歧義。
例如:
1
2
3
COUNT=5
echo COUNTecho {COUNT}911
通配符 Globbing、指令代換、單引号、雙引号
1.常見的通配符:
- : 比對0個或多個任意字元
? : 比對一個任意字元
[若幹字元] : 比對方括号中任意一個字元的一次出現
2.指令代換:
反引号“ 或者 $()
script.sh :
shell會先執行反引号或$()中的指令,将結果代換到目前指令行中!
反引号和$()的差別:
反引号本身就對\進行了轉義,保留了本身意思,如果我們想在反引号中起到\的特殊意義,我們必須使用2個\來進行表示。
反引号中: \\ = \
$()中:\ = \
注意:反引号是老的用法,()是新的用法,不管是在學習測試中,還是在實際工作中,()是新的用法,不管是在學習測試中,還是在實際工作中,()的用法都是被推薦的。
算數代換:$(())
例如:将2-1的結果賦給SUB,并顯示本地變量SUB
1
2
SUB= ((2−1))echo SUB
3.單引号和雙引号
Shell腳本中的單引号和雙引号一樣都是字元串的界定符,單引号用于保持引号内所有字元的字面值,而雙引号有些情況則特殊。如果字元串中有特殊字元需要處理時就用雙引号。
注:單引号标注的字元中不能再出現單引号。
舉個栗子:
1
2
3
4
5
6
!/bin/bash
echo ‘\’
echo “\”
echo ‘
date
’
echo “
date
”