sh 編寫
1 基本語法
1.1 變量
變量類型
- 局部變量
局部變量在腳本或命令中定義,僅在當前shell實例中有效,其他shell啓動的程序不能訪問局部變量。 - 環境變量
所有的程序,包括shell啓動的程序,都能訪問環境變量,有些程序需要環境變量來保證其正常運行。必要的時候shell腳本也可以定義環境變量。 - shell變量
shell變量是由shell程序設置的特殊變量。
定義變量
- 定義變量時,變量名不加美元符號($),如:
variableName=“value” - 注意,變量名和等號之間不能有空格。
- 變量名的命名須遵循如下規則:
1、 首個字符必須爲字母(a-z,A-Z)。
2、中間不能有空格,可以使用下劃線(_)。
3、不能使用標點符號。
4、不能使用bash裏的關鍵字(可用help命令查看保留關鍵字)。
使用變量
- 使用一個定義過的變量,只要在變量名前面加美元符號($)即可,如:
hello_world=“hello_world ni hao”
echo $hello_world
echo ${hello_world} - 變量名外面的花括號是可選的,加不加都行,加花括號是爲了幫助解釋器識別變量的邊界,比如下面這種情況:
echo “I am good at ${skill}Script”
如果不給skill變量加花括號,寫成echo “I am good at $skillScript”,解釋器就會把$skillScript當成一個變量 - 推薦給所有變量加上花括號,這是個好的編程習慣。
重新定義變量
- 已定義的變量,可以被重新定義,如:
int_aa=111
echo ${int_aa}
int_aa=222
echo ${int_aa} - 這樣寫是合法的,但注意,第二次賦值的時候不能加美元符
只讀變量
- 使用 readonly 命令可以將變量定義爲只讀變量,只讀變量的值不能被改變。
int_aa=111
readonly int_aa
int_aa=222 - 運行時提示:/bin/sh: NAME: This variable is read only.
刪除變量
- 使用 unset 命令可以刪除變量。
- 變量被刪除後不能再次使用;unset 命令不能刪除只讀變量。
int_aa=111
unset int_aa
echo ${int_aa}
1.2 命令行參數
- 運行腳本時傳遞給腳本的參數稱爲命令行參數。命令行參數用 ${n} 表示。
特殊變量列表
變量 | 含義 |
---|---|
$0 | 當前腳本的文件名 |
$n | 傳遞給腳本或函數的參數。n 是一個數字,表示第幾個參數。例如,第一個參數是$1,第二個參數是$2。 |
$# | 傳遞給腳本或函數的參數個數。 |
$* | 傳遞給腳本或函數的所有參數。 |
$@ | 傳遞給腳本或函數的所有參數。被雙引號(" ")包含時,與 $* 稍有不同 |
$? | 上個命令的退出狀態,或函數的返回值。 |
$$ | 當前Shell進程ID。對於 Shell 腳本,就是這些腳本所在的進程ID。 |
- $* 和 $@的區別 當它們被雙引號(" “)包含時,”$*" 會將所有的參數作爲一個整體,以"$1 $2 … @" 會將各個參數分開,以"$1" “$2” … “$n” 的形式輸出所有參數。
- 退出狀態 $?: 可以獲取上一個命令的退出狀態。所謂退出狀態,就是上一個命令執行後的返回結果。
退出狀態是一個數字,一般情況下,大部分命令執行成功會返回 0,失敗返回 1。
變量替換
- 變量替換可以根據變量的狀態(是否爲空、是否定義等)來改變它的值
形式 | 說明 |
---|---|
${var} | 變量本來的值 |
${var:-word} | 如果變量 var 爲空或已被刪除(unset),那麼返回 word,但不改變 var 的值。 |
${var:=word} | 如果變量 var 爲空或已被刪除(unset),那麼返回 word,並將 var 的值設置爲 word。 |
${var:?message} | 如果變量 var 爲空或已被刪除(unset),那麼將消息 message 送到標準錯誤輸出,可以用來檢測變量 var 是否可以被正常賦值。若此替換出現在Shell腳本中,那麼腳本將停止運行。 |
${var:+word} | 如果變量 var 被定義,那麼返回 word,但不改變 var 的值。 |
1.3 運算符
算術運算符
運算符 | 說明 | 舉例 |
---|---|---|
+ | 加法 | `expr $a + $b` 結果爲 30。 |
- | 減法 | `expr $a - $b` 結果爲 10。 |
* | 乘法 | `expr $a * $b` 結果爲 200。 |
/ | 除法 | `expr $b / $a` 結果爲 2。 |
% | 取餘 | `expr $b % $a` 結果爲 0。 |
= | 賦值 | a=$b 將把變量 b 的值賦給 a。 |
== | 相等。 | 用於比較兩個數字,相同則返回 true。 [ $a == $b ] 返回 false。 |
!= | 不相等。 | 用於比較兩個數字,不相同則返回 true。 [ $a != $b ] 返回 true。 |
關係運算符
- 關係運算符只支持數字,不支持字符串,除非字符串的值是數字。
運算符 | 說明 | 舉例 |
---|---|---|
-eq | 檢測兩個數是否相等,相等返回 true。 | [ $a -eq $b ] 返回 true。 |
-ne | 檢測兩個數是否相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 檢測左邊的數是否大於右邊的,如果是,則返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 檢測左邊的數是否小於右邊的,如果是,則返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 檢測左邊的數是否大等於右邊的,如果是,則返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。 | [ $a -le $b ] 返回 true。 |
布爾運算符
運算符 | 說明 | 舉例 |
---|---|---|
! | 非運算,表達式爲 true 則返回 false,否則返回 true。 | [ ! false ] 返回 true。 |
-o | 或運算,有一個表達式爲 true 則返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 與運算,兩個表達式都爲 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
字符串運算符
運算符 | 說明 | 舉例 |
---|---|---|
= | 檢測兩個字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 檢測兩個字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 檢測字符串長度是否爲0,爲0返回 true。 | [ -z $a ] 返回 false。 |
-n | 檢測字符串長度是否爲0,不爲0返回 true。 | [ -z $a ] 返回 true。 |
str | 檢測字符串是否爲空,不爲空返回 true。 | [ $a ] 返回 true。 |
文件測試運算符
文件測試運算符用於檢測 Unix 文件的各種屬性。
運算符 | 說明 | 舉例 |
---|---|---|
-b | file 檢測文件是否是塊設備文件,如果是,則返回 true。 | [ -b $file ] 返回 false。 |
-c | file 檢測文件是否是字符設備文件,如果是,則返回 true。 | [ -b $file ] 返回 false。 |
-d | file 檢測文件是否是目錄,如果是,則返回 true。 | [ -d $file ] 返回 false。 |
-f | file 檢測文件是否是普通文件(既不是目錄,也不是設備文件),如果是,則返回 true。 | [ -f $file ] 返回 true。 |
-g | file 檢測文件是否設置了 SGID 位,如果是,則返回 true。 | [ -g $file ] 返回 false。 |
-k | file 檢測文件是否設置了粘着位(Sticky Bit),如果是,則返回 true。 | [ -k $file ] 返回 false。 |
-p | file 檢測文件是否是具名管道,如果是,則返回 true。 | [ -p $file ] 返回 false。 |
-u | file 檢測文件是否設置了 SUID 位,如果是,則返回 true。 | [ -u $file ] 返回 false。 |
-r | file 檢測文件是否可讀,如果是,則返回 true。 | [ -r $file ] 返回 true。 |
-w | file 檢測文件是否可寫,如果是,則返回 true。 | [ -w $file ] 返回 true。 |
-x | file 檢測文件是否可執行,如果是,則返回 true。 | [ -x $file ] 返回 true。 |
-s | file 檢測文件是否爲空(文件大小是否大於0),不爲空返回 true。 | [ -s $file ] 返回 true。 |
-e | file 檢測文件(包括目錄)是否存在,如果是,則返回 true。 | [ -e $file ] 返回 true。 |
1.4 字符串
- sh裏沒有多行註釋,只能每一行加一個#號。
- 字符串是shell編程中最常用最有用的數據類型(除了數字和字符串,也沒啥其它類型好用了),字符串可以用單引號,也可以用雙引號,也可以不用引號。單雙引號的區別跟PHP類似。
單引號
單引號字符串的限制:
- 單引號裏的任何字符都會原樣輸出,單引號字符串中的變量是無效的;
- 單引號字串中不能出現單引號(對單引號使用轉義符後也不行)。
雙引號
雙引號的優點:
- 雙引號裏可以有變量
- 雙引號裏可以出現轉義字符
拼接字符串
-
拼接字符串有兩種操作:
your_name=“hehehe”
greeting=“hello,”$your_name"!"
echo KaTeX parse error: Expected '}', got '#' at position 2: {#̲greeting} greet…{your_name}!"
echo ${#greeting_1}
echo $greeting $greeting_1 -
output:
13
13
hello,hehehe! hello,hehehe!
獲取字符串長度
- string=“abcd”
echo ${#string} #輸出 4
提取子字符串
- string=“alibaba is a great company”
echo ${string:1:4} #輸出liba
查找子字符串
- string=“alibaba is a great company”
echo `expr index “$string” is`
1.5 數組
定義數組
- 在Shell中,用括號來表示數組,數組元素用“空格”符號分割開。定義數組的一般形式爲:
array_name=(value1 … valuen)
例如:
- array_name=(value0 value1 value2 value3)
- array_name=(
value0
value1
value2
value3
) - array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
可以不使用連續的下標,而且下標的範圍沒有限制。
讀取數組
- 讀取數組元素值的一般格式是:
${array_name[index]}
獲取數組的長度
- #取得數組元素的個數
length=${#array_name[@]} - #或者
length=${#array_name[*]} - #取得數組單個元素的長度
lengthn=${#array_name[n]}
顯示轉義字符
- echo ““It is a test””
“It is a test” (雙引號也可以省略。)
2 操作
2.1 if 語句
if … fi 語句;
if … else … fi 語句;
if … elif … else … fi 語句。
if … fi 語句
if ... else 語句的語法:
if [ expression ]
then
Statement(s) to be executed if expression is true
fi
注意:expression 和方括號([ ])之間必須有空格,否則會有語法錯誤。
if … else … if 語句
if ... else ... fi 語句的語法:
if [ expression ]
then
Statement(s) to be executed if expression is true
else
Statement(s) to be executed if expression is not true
fi
if … elif … fi 語句
if … elif … fi 語句可以對多個條件進行判斷,語法爲:
if [ expression 1 ]
then
Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
Statement(s) to be executed if expression 3 is true
else
Statement(s) to be executed if no expression is true
fi
2.2 case
- case … esac 與其他語言中的 switch … case 語句類似,是一種多分枝選擇結構。
case 語句匹配一個值或一個模式,如果匹配成功,執行相匹配的命令。case語句格式如下:
case 值 in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac
2.3 for
for循環一般格式爲:
for 變量 in 列表
do
command1
command2
...
commandN
done
2.4 break
- break 命令允許跳出所有循環(終止執行後面的所有循環)。
- break n
表示跳出第 n 層循環。
2.5 continue
continue命令與break命令類似,只有一點差別,它不會跳出所有循環,僅僅跳出當前循環。
2.6 輸出重定向
- 命令的輸出不僅可以是顯示器,還可以很容易的轉移向到文件,這被稱爲輸出重定向。
- 命令輸出重定向的語法爲:
$ command > file
這樣,輸出到顯示器的內容就可以被重定向到文件。
2.7 輸入重定向
和輸出重定向一樣,Unix 命令也可以從文件獲取輸入,語法爲:
command < file
這樣,本來需要從鍵盤獲取輸入的命令會轉移到文件讀取內容。
注意:輸出重定向是大於號(>),輸入重定向是小於號(<)。
2.10 批量執行命令
sh findpcap.sh
sh extractor.sh
3.參考
ubuntu中寫sh腳本
ubuntu的sh文件編程(一)
ubuntu的sh文件編程(二)
Ubuntu系統中sh腳本編寫