簡明 linux shell script 入門

前言
Shell 是一種讓使用者可以和作業系統 Kernel(核心用來控制 CPU、記憶體、硬碟等硬體)互動溝通的橋樑。Shell Script 主要是使用在 Linux 和 MacOS 等 Unix-like 作業系統的自動化操作指令的程式語言。其透過 Unix shell 命令列直譯器來執行(我們這邊主要使用 bash shell,其他的 Unix shell 觀念大致類似),使用方式有點類似直譯式程式語言(不用編譯直接執行)。在 Windows 系列家族也有類似的使用方式:Batch file。

一般情況 Shell Script 常用於系統管理、自動化操作檔案、自動化重複的指令碼、分析 log 等文件檔案、列印呈現我們想要的資料等,透過程式語言的使用來減少重複瑣碎的工作,所以若能妥善使用將提升不少開發者和軟體工程師的日常工作效率。接著我們將透過日常 生活常用的使用情境,帶領讀者們進入入門 Shell Script(讀者需要具備基本 Linux 指令碼的基本觀念,若你需要複習常見 Linux 指令可以參考 Linux Command 命令列指令與基本操作入門教學)。
Shell Script 初體驗
在撰寫 Shell Script 之前我們先來了解 Shell Script 撰寫的流程和架構。一般我們會使用 .sh 副檔名來命名 Shell Script 檔案。然後將該檔案設定為可執行:
chmod +x demo.sh
可以透過檢視檔案詳細資料觀看是否已有 +x 的執行權限:
ls -l demo.sh
# -rwxr-xr-x 1 user staff 106 Nov 16 10:41 demo.sh
執行 Shell Script 檔案:
./demo.sh
接著,我們先利用一個簡單的範例:將目前執行 process 的 PID 依照數字大小排序,取出前 10 名,來了解撰寫 Shell Script 的基本架構。
# 宣告使用 /bin/bash
#!/bin/bash
echo "=== 將目前執行 process 的 PID 依照數字大小排序,取出前 10 名 === "
# ps 為列出 process 相關資訊,透過 | pipe 管線傳遞 資料。
# awk 可以根據 pattern 進行資料處理(這邊印出第一欄 PID)
# 而 sort 是進行排序,其排序時,預設都是把資料當作字串來排序,若想讓資料根據實際數值的大小來排序,可以加上 -n 參數。-r 則是由大到小排序,預設是由小到大
ps | awk '{print $1}' | sort -rn | head -10
執行結果:
$ ./demo.sh
=== 將目前執行 process 的 PID 依照數字大小排序,取出前 10 名 ===
83784
83783
75956
75955
75954
75952
74069
74068
73543
37621
恭喜你,你已經完成了第一個 Shell Script 程式了!
變數
一般來說程式語言中變數是用來暫存接下來會使用到的資料或是儲存指到物件的參考位置。在 Shell Script 可以使用以下三種方式來宣告變數並給定值:
#!/bin/bash
variable1=value
# 若是值內有空白則需要使用 '' 或 "" 包裹起來
variable2='value 2'
variable3="value 3"
註解使用 #,因為沒有多行註解,所以需要使用多單行註解達到
使用變數方式為 ${變數名稱},花括號主要是輔助了解變數 的範圍:
#!/bin/bash
pathName=demo.sh
# echo 是列印值,印出變數 pathName 內容 demo.sh
echo ${pathName}
更新變數直接重新 assign 值即可:
#!/bin/bash
pathName=demo1.sh
# 印出 demo1.sh
echo ${pathName}
pathName=demo2.sh
# 印出 demo2.sh
echo ${pathName}
刪除變數使用 unset:
#!/bin/bash
pathName=demo.sh
# 印出 demo.sh
echo ${pathName}
unset pathName
# 空值
echo ${pathName}
注意系統環境變數為全域變數、區域變數則為 Shell Script 內部程式使用,不能跨檔案使用。
運算式
運算式是當運算子和運算元計算結果回傳後賦值給變數。在 Bash Shell 中內建原生不支援運算式,但我們可以使用 expr、awk 等指令來支援實現運算式。
算式
我們可以使用四則運算來賦值:
#!/bin/bash
result=`expr 10 + 2`
# 12
echo "Result: $result"
條件判斷
在 Shell Script 中同樣可以使用 if..else 條件判斷,特別注意的是在 Shell Script 中使用 fi 為結尾(為 if 的倒寫法,同樣的接下來討論的 case 也有類似用法),代表條件判斷結束。== 為等於,!= 為不等於運算子。
if
#!/bin/sh
x=20
y=30
if [ $x == $y ]; then
echo "value x is equal to value y"
fi
if [ $x != $y ]; then
echo "value x is not equal to value y"
fi
if else
在 Shell Script 可以使用 -gt (greater than 縮寫)和 -lt (less than 縮寫)代表大於和小於,而 -ge (greater equal 縮寫)和 -le(less equal 縮寫)則是大於等於和小於等於的運算子符號。
記得比較條件需要放在 [] 中,前後要留空白
#!/bin/bash
if [ $x -gt $y ]; then
echo "value x is greater than value y"
else
echo "value x is not greater than value y"
fi
if [ $x -lt $y ]; then
echo "value x is not less than value y"
else
echo "value x is not less than value y"
fi
if [ $x -ge $y ]; then
echo "value x is greater or equal than value y"
else
echo "value x is not greater than value y"
fi
if [ $x -le $y ]; then
echo "value x is not less or equal than value y"
else
echo "value x is not less or equal than value y"
fi
if elif else
若有多個條件需要判斷,可以使用 if elif else:
#!/bin/bash
value1=20
value2=30
value3=30
if [ $value1 -gt $value2 ]; then
echo "value1 is greater than value2"
elif [ $value1 == $value3 ]; then
echo "value1 is equal to value3"
else
echo "other result"
fi
case ... esac
若要使用類似一般程式語言的 switch 來處理多種條件判斷時,可以使用 case 來進行判斷:
#!/bin/bash
language='Java'
case $language in
Java*) echo "是 Java!"
;;
Python*) echo "是 Python!"
;;
C*) echo "是 C!"
;;
*) echo "沒 match 到!"
esac