Shell 程式設計詳細指南
什麼是 Shell?
Shell 是使用者與作業系統核心之間的介面,允許使用者透過命令列輸入來控制作業系統。它充當命令直譯器,讀取使用者輸入的命令並執行相應的操作。Shell 提供了強大的指令碼程式設計能力,可以自動化許多工。常見的 Shell 有 Bash(Bourne Again Shell)、Zsh(Z Shell)、Ksh(Korn Shell)等。
什麼是 Shell 指令碼?
Shell 指令碼是一種程式語言指令碼,用於在 Unix/Linux 作業系統上執行命令。它是一系列命令的集合,通常儲存在一個檔案中,可以透過執行指令碼檔案來執行這些命令。
1. 註釋
單行註釋
在 Shell 指令碼中,註釋是透過 #
字元來實現的。任何在 #
後面的內容都會被忽略,不會被執行。
# 這是一個單行註釋
# echo "Hello, World!"
文章下面講的是shell是Bash的語法, 所有語法可以直接在終端使用, 也可以寫在一個 .bash
或 .sh
的檔案中, 然後透過 ./filename
來執行。(要想執行, 需要給檔案可執行的許可權, 下面會講到)
檔案開頭先寫上下面內容,
#!/bin/bash
#!/bin/bash
是一種稱為 "shebang" 或 "hashbang" 的特殊註釋,用於指定指令碼的直譯器。
作用
-
指定直譯器:
#!/bin/bash
告訴作業系統這個指令碼應該由/bin/bash
程式來解釋執行。/bin/bash
是 Bash(Bourne Again Shell)的路徑。 -
執行許可權:當你在 Unix/Linux 系統中執行一個指令碼時,作業系統會根據這個 shebang 行來決定用哪個直譯器來執行指令碼內容。
#!/bin/bash
使得指令碼能夠以 Bash 語言執行,即使指令碼的副檔名不是.sh
。
2. 變數
變數定義與使用
在 Shell 中,變數的定義不需要使用資料型別。可以直接用 =
號賦值,不要在 =
號兩邊加空格。變數的值可以透過 $
符號來引用。
my_var="Hello, World!"
echo $my_var
變數命名規則
- 變數名只能包含字母、數字和下劃線。
- 變數名不能以數字開頭。
- 變數名通常使用大寫字母以提高可讀性(不是強制要求)。
變數型別
- 字串變數
name="John Doe"
echo "Hello, $name"
- 整數變數
number=42
echo "The number is $number"
陣列
陣列賦值
arr=(value1 value2 value3)
讀取陣列元素
echo ${arr[1]}
變數操作
變數替換
變數替換是指將變數的值插入到字串中。
echo "My name is ${name}."
只讀變數
定義只讀變數後,其值不能被修改。
readonly val="value"
val="new_value" # 這將會報錯
3. 環境變數
環境變數是可以在整個系統中使用的變數。它們通常在 Shell 會話開始時定義,可以影響系統的行為和操作。常見的環境變數有 PATH
、HOME
、USER
等。
定義和匯出環境變數
使用 export
命令可以將變數設定為環境變數。
export MY_ENV_VAR="value"
檢視環境變數
使用 printenv
或 env
命令可以檢視當前所有環境變數。
printenv
env
4. 常用 Shell 變數
- $0:當前指令碼的檔名。
- $1, $2, ...:傳遞給指令碼或函式的引數。
- $#:傳遞給指令碼或函式的引數個數。
- $@:傳遞給指令碼或函式的所有引數。
- $?:上個命令的退出狀態。
- $$:當前 Shell 程序的 PID。
- $!:後臺執行的最後一個程序的 PID。
5. 輸入輸出
read
命令
read
命令用於從標準輸入讀取一行輸入,並將其分配給一個或多個變數。
基本用法
echo "Enter your name:"
read name
echo "Hello, $name!"
使用選項
-p
提示符-s
隱藏輸入(常用於密碼)-t
設定超時-n
限制輸入字元數
read -p "Enter your username: " username
read -s -p "Enter your password: " password
echo
echo "Username: $username"
echo
命令
echo
命令用於輸出字串到標準輸出。
基本用法
echo "Hello, World!"
使用選項
-n
不換行-e
解析反斜槓跳脫字元
echo -n "Hello, "
echo "World!"
echo -e "Line1\nLine2\nLine3"
printf
命令
printf
命令用於格式化輸出,類似於 C 語言中的 printf
函式。
printf "Hello, %s!\n" "World"
常見格式說明符
%s
字串%d
十進位制整數%f
浮點數%x
十六進位制數
name="John"
age=25
printf "Name: %s, Age: %d\n" "$name" "$age"
6. 條件判斷
判斷語句
if
語句
if [ condition ]; then
# statements
elif [ condition ]; then
# statements
else
# statements
fi
樣例:
#!/bin/bash
number=5
# gt lt 分別是 > 和 <
if [ $number -gt 0 ]; then
echo "The number is positive."
elif [ $number -lt 0 ]; then
echo "The number is negative."
else
echo "The number is zero."
fi
case
語句
case "$variable" in
pattern1)
# statements
;;
pattern2)
# statements
;;
*)
# default statements
;;
esac
樣例:
#!/bin/bash
echo "Enter a single character (a-g):"
read char
case "$char" in
a)
echo "Monday"
;;
b)
echo "Tuesday"
;;
c)
echo "Wednesday"
;;
d)
echo "Thursday"
;;
e)
echo "Friday"
;;
f)
echo "Saturday"
;;
g)
echo "Sunday"
;;
*)
echo "Invalid input"
;;
esac
test
命令
test
命令用於條件判斷,常與邏輯運算子結合使用。
檔案測試
-e
檔案存在-f
檔案是普通檔案-d
檔案是目錄
if test -e /etc/passwd; then
echo "/etc/passwd exists."
fi
字串測試
-z
字串為空-n
字串非空=
字串相等!=
字串不相等
if test -z "$name"; then
echo "Name is empty."
fi
數值測試
-eq
等於-ne
不等於-gt
大於-lt
小於-ge
大於或等於-le
小於或等於
if test $age -gt 20; then
echo "Age is greater than 20."
fi
7. 迴圈語句
for
迴圈
for var in list; do
# statements
done
for i in {1..5}; do
echo "Number: $i"
done
while
迴圈
while [ condition ]; do
# statements
done
counter=1
while [ $counter -le 5 ]; do
echo "Counter: $counter"
counter=$((counter + 1))
done
until
迴圈
until [ condition ]; do
# statements
done
counter=1
until [ $counter -gt 5]; do
echo "Counter: $counter"
counter=$((counter + 1))
done
8. 函式
Shell 函式用於封裝程式碼塊,以便多次呼叫。
定義函式
function_name() {
# statements
}
greet() {
echo "Hello, $1!"
}
greet "World"
帶返回值的函式
add() {
result=$(( $1 + $2 ))
return $result
}
add 2 3
echo "Sum: $?"
綜合示例
#!/bin/bash
# 函式定義
print_menu() {
echo "1. Say Hello"
echo "2. Display Date"
echo "3. Exit"
}
# 主程式
while true; do
print_menu
read -p "Enter your choice: " choice
case $choice in
1)
read -p "Enter your name: " name
echo "Hello, $name!"
;;
2)
current_date=$(date)
echo "Current date and time: $current_date"
;;
3)
echo "Goodbye!"
break
;;
*)
echo "Invalid choice, please try again."
;;
esac
done
結論
上述內容涵蓋了 Shell 指令碼程式設計中的基礎部分,包括輸入輸出、變數和函式、條件判斷和迴圈等。透過理解和掌握這些內容,你可以編寫功能強大的 Shell 指令碼來