技能篇:shell教程及指令碼編寫
阿新 • • 發佈:2021-06-16
前言
我們常時不會見到shell指令碼,但是需要閱讀開發linux指令碼時,這又是一項必不可少的技能。本文在於提供基礎的shell程式設計語法和簡單的例項,幫助同學快速開發,可當做shell手冊使用也非常善
- shell指令碼的執行和模組載入
- shell中的變數
- 位置引數和預定義變數
- 表示式的運算命令
- 表示式判斷符號及相關操作符
- 跳轉條件語句
- shell陣列和字典
- shell自定義函式
- shell程式中常用命令
關注公眾號,一起交流,微信搜一搜: 潛行前行
shell指令碼的執行和模組載入
- shell指令碼的執行
bash scriptName
或sh scriptName
,當指令碼檔案本身沒有執行許可權時常使用的方法path/scriptName
或./scriptName
,在當前路徑下執行指令碼,需要將指令碼檔案的許可權改為可執行source scriptName
或. scriptName
,通常是使用source或 "." 讀入或載入指定的Shell指令碼檔案,然後依次執行指定的Shell指令碼中的語句
- shell規範
- 一個規範的Shell指令碼在第一行會指出由哪個程式(直譯器)來執行指令碼中的內容,這一行內容Linux bash的程式設計一般為:#!/bin/bash 或 #! /bin/sh,bash與sh的區別 , sh為bash的軟連線
shell 中的變數
- 變數的賦值方法為: 先寫變數名稱,緊接著是 "=" ,最後是值,中間無任何空格
賦值時使用帶引號的作用
- 雙引號:允許通過 $ 符號引用其他變數值
- 單引號:禁止引用其他變數值,$ 視為普通字元
- 反引號:命令替換,提取命令執行後的輸出結果
- 示例
--- 雙引號 ----
server11:~ # A=hello
hello
server11:~ # B="$A lwl"
hello lwl
--- 單引號 ---
server11:~ # B='$A lwl'
$A lwl
---- 反引號 -----
server11:~ # B=`du -sh /etc`
21M /etc # du -sh /etc 的執行結果
位置引數和預定義變數
- 預定義變數
符號 | 描述 |
---|---|
$# | 位置引數的數量 |
$* | 所有位置引數的內容 |
$? | 命令執行後返回的狀態,0表示沒有錯誤,非0表示有錯誤 |
$$ | 當前程序的程序號 |
$! | 後臺執行的最後一個程序號 |
$0 | 當前執行的程序名 |
${n} | 第 {n} 個位置引數 |
- shell取第一個位置引數替換程式檔案中的 $1,第二個替換 $2 , 依次類推。$0 是一個特殊變數,它的內容是當前這個shell程式的檔名
server11:~ # cat test.sh
#! /bin/bash
echo $1
server11:~ # bash test.sh lwl
lwl
表示式的運算命令
- Shell 中常見的算術運算命令
運算子 | 描述 |
---|---|
(( expresions )) | 用於整數運算的運算命令 |
let expresions | 類似(()),常用於賦值表示式 |
expr expresions | 可用於 整數運算,可執行命令 |
$[ expresions ] | 用於整數運算 |
- 對於(())運算命令,其返回值需要使用$ 修飾,如: i=$(($A+3))
- 示例
server11:~ # A=10
server11:~ # B=$(($A+5))
server11:~ # echo $B
15
表示式判斷符號及相關操作符
- 表示式判斷符號
判斷符號 | 描述 |
---|---|
test condition | 利用test命令進行條件判斷 |
[ condition ] | 利用中扣號命令進行條件判斷 |
[[ condition ]] | 利用雙中扣號命令進行條件判斷 |
(( condition )) | 不能用於字串比較 |
- 檔案判斷操作符
檔案判斷操作符 | 描述 |
---|---|
-d(directory) | 檔案存在且為目錄則為真 |
-f(file) | 檔案存在且為檔案則為真 |
-e (exists) | 檔案存在則為真 |
-s (size) | 檔案存在且大小不為0則為真 |
-r (read) | 檔案存在且可讀則為真 |
-w (write) | 檔案存在且可寫則為真 |
-x (executable) | 檔案存在且可執行則為真 |
-L (link) | 檔案存在且為連結檔案則為真 |
f1 -ntf2,nt的全拼為newerthan | 檔案f1比檔案f2新則為真 |
f1 -otf2 ,ot的全拼為older than | 檔案f1比檔案f2舊則為真 |
- 字串判斷操作符( == 和 != 兩端要有空格, (()) 不能用於字元判斷)
常用字串判斷操作符 | 描述 |
---|---|
-n | 若字串長度不為0,則為真 |
-z | 若字串長度為0,則為真 |
"str1" == "str2" | 若str1等於str2,則為真 |
"st1" != "str2" | 若str1不等於str2,則為真 |
- 整數比較操作符
在[]以及test中使用的比較符號 | 在(())和[[]]中使用的比較符號 | 描述 |
---|---|---|
-eq | ==或 = | 相等(equal) |
-ne | != | 不相等(notequal) |
-gt | > | 大於(greaterthan) |
-ge | >= | 大於等於(greaterequal) |
-lt | < | 小於(less than) |
-le | <= | 小於等於(lessequal) |
- 邏輯操作符
在[]和test中使用的邏輯操作符 | 在[[]]和(())中使用的操作符 | 描述 |
---|---|---|
-a | && | and ,與,兩端都為真,才為真 |
-o | || | or ,或, 兩端有一個為真,就為真 |
! | ! | not ,非, 兩端相反,則結果為真 |
- 表示式判斷符號 test 、[] 、[[]] 、 (())的區別
表示式判斷符號 | test | [] | [[]] | (()) |
---|---|---|---|---|
邊界是否需要空格 | 需要 | 需要 | 需要 | 不需要 |
邏輯操作符 | ! 、-a、 -o | ! 、-a、 -o | ! 、&& 、 || | ! 、&& 、 |\ |
整數比較操作符 | -eq 、 -gt 、-lt、-ge 、-le | -eq 、 -gt 、-lt、-ge 、-le | -eq 、 -gt 、-lt、-ge 、-le或 = 、> 、< 、 >= 、 <= | = 、> 、< 、 >= 、 <= |
字串比較操作符 | = 、 == 、!= | = 、 == 、!= | = 、 == 、!= | 不支援 |
檔案操作 | -d、-f、-e、-r、-s、-w、-x、-L、-nt、-ot | -d、-f、-e、-r、-s、-w、-x、-L、-nt、-ot | -d、-f、-e、-r、-s、-w、-x、-L、-nt、-ot | 不支援 |
是否支援萬用字元匹配 | 不支援 | 不支援 | 支援 | 不支援 |
- 示例
server11:~ # [ 1 == 1 -a 2 == 3 ] && echo true # 2不等於3,因此true沒打印出來
server11:~ # [ 1 == 1 -a 2 == 2 ] && echo true
true
跳轉條件語句
- if 條件關鍵字
if 條件判斷;then
邏輯程式碼
else
邏輯程式碼
fi
-------------------------
server11:~ # choose="lwl"
server11:~ # if [ choose == "lwl" ];then
> echo true
> else
> echo false
> fi;
false
- case 條件語句
case 變數 in
one)
邏輯程式碼
;;
two)
邏輯程式碼
;;
*)
邏輯程式碼
esac
- for 迴圈語句
for 條件;do
邏輯程式碼
done
-------------
server11:~ # for (( i=0;i<2;i++ ));do
> echo $i
> done;
0
1
- while 迴圈語句
while 條件
do
邏輯程式碼
done
-------------------------
server11:~ # i=0
server11:~ # while [[ $i -lt 2 ]];do
> let i++
> echo $i
> done;
1
2
- break、continue、exit 迴圈控制語句
- Break跳出for while 迴圈
- Continue跳過當次迴圈,執行下一次迴圈
- exit直接退出程式
shell陣列和字典
- 陣列
#方式一
server11:~ # array=(A B "C" D)
#方式二
server11:~ # array[0]='csc'
server11:~ # array[1]='lwl'
server11:~ # echo ${#array[*]} ## 獲取陣列長度 陣列的長度 ${#array[@]} 和 ${#array[*]}
2
server11:~ # for((i=0;i<${#array[@]};i++)); do echo ${array[$i]}; done;
csc ## 下標遍歷
lwl
server11:~ # for i in ${array[@]}; do echo $i; done;
csc ## 直接遍歷value
lwl
- 字典
server11:~ # declare -A dic ## 宣告 dic
server11:~ # dic=([csc]="hello" [lwl]="world")
server11:~ # echo ${!dic[*]}
lwl csc ## 列印所有key
server11:~ # echo ${dic[*]}
world hello ## 列印所有value
server11:~ # echo ${dic["lwl"]}
world ## 列印指定key的value
server11:~ # for key in $(echo ${!dic[*]}) ##遍歷 dic
> do
> echo "$key : ${dic[$key]}"
> done;
lwl : world
csc : hello
shell自定義函式
function funcName(){
echo "data: $1"
}
-----函式呼叫----
server11:~ # source func.sh
server11:~ # funcName 10
data: 10
- 引用自定義函式檔案時,使用
source func.sh
載入檔案 - 函式傳遞引數(可以使用類似於Java中的args,args[1]代表Shell中的 $1)
shell程式中常用命令
- shell程式可使用在shell互動介面的一切命令
常用的命令方法 | 描述 |
---|---|
git | 程式碼版本控制 |
awk、sed | 文字處理命令 |
mvn | java服務常用的打包命令 |
java | jvm 啟動相關 |
docker | 服務docker映象打包 |
kubectl | k8s相關部署命令 |