Ubuntu 22.04 Shell Scripting Automation 本文將介紹在 Ubuntu 22.04 環境下撰寫 Shell Script 的完整指南,從基礎語法到進階技巧,幫助你實現系統管理自動化。
Shell Script 基礎 Shell Script 是一種命令列直譯器腳本,在 Linux 系統中最常用的是 Bash(Bourne Again Shell)。
建立第一個腳本 1
2
3
#!/bin/bash
# 這是我的第一個 Shell Script
echo "Hello, Ubuntu 22.04!"
儲存為 hello.sh 後,需要賦予執行權限:
1
2
chmod +x hello.sh
./hello.sh
變數與參數 變數宣告與使用 1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
# 變數宣告(等號前後不能有空格)
NAME = "Ubuntu"
VERSION = "22.04"
# 使用變數
echo "系統名稱: $NAME "
echo "版本號碼: ${ VERSION } "
# 唯讀變數
readonly SYSTEM_NAME = "Linux"
# 環境變數
export MY_PATH = "/usr/local/bin"
位置參數 1
2
3
4
5
6
7
8
#!/bin/bash
# 位置參數範例
echo "腳本名稱: $0 "
echo "第一個參數: $1 "
echo "第二個參數: $2 "
echo "所有參數: $@ "
echo "參數個數: $# "
echo "上一個命令的退出狀態: $? "
特殊變數 變數 說明 $0腳本名稱 $1-$9位置參數 $#參數個數 $@所有參數(分開) $*所有參數(合併) $$目前程序 PID $?上一個命令的退出狀態
條件判斷 if-else 語句 1
2
3
4
5
6
7
8
9
10
#!/bin/bash
FILE = "/etc/passwd"
if [ -f " $FILE " ] ; then
echo "檔案 $FILE 存在"
elif [ -d " $FILE " ] ; then
echo " $FILE 是一個目錄"
else
echo "檔案 $FILE 不存在"
fi
數值比較運算子 1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
NUM1 = 10
NUM2 = 20
if [ $NUM1 -eq $NUM2 ] ; then
echo "相等"
elif [ $NUM1 -lt $NUM2 ] ; then
echo " $NUM1 小於 $NUM2 "
elif [ $NUM1 -gt $NUM2 ] ; then
echo " $NUM1 大於 $NUM2 "
fi
運算子 說明 -eq等於 -ne不等於 -lt小於 -le小於等於 -gt大於 -ge大於等於
case 語句 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
read -p "請輸入選項 (1-3): " OPTION
case $OPTION in
1)
echo "你選擇了選項 1"
;;
2)
echo "你選擇了選項 2"
;;
3)
echo "你選擇了選項 3"
;;
*)
echo "無效的選項"
;;
esac
迴圈結構 for 迴圈 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# 基本 for 迴圈
for i in 1 2 3 4 5; do
echo "數字: $i "
done
# C 風格 for 迴圈
for (( i = 0; i<5; i++)) ; do
echo "計數: $i "
done
# 遍歷檔案
for file in /var/log/*.log; do
echo "日誌檔案: $file "
done
while 迴圈 1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
COUNT = 1
while [ $COUNT -le 5 ] ; do
echo "第 $COUNT 次迴圈"
(( COUNT++))
done
# 讀取檔案內容
while IFS = read -r line; do
echo "行內容: $line "
done < "/etc/hosts"
until 迴圈 1
2
3
4
5
6
7
#!/bin/bash
NUM = 1
until [ $NUM -gt 5 ] ; do
echo "數字: $NUM "
(( NUM++))
done
函數定義 基本函數 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
# 定義函數
say_hello() {
echo "你好, $1 !"
}
# 帶有回傳值的函數
add_numbers() {
local result = $(( $1 + $2 ))
echo $result
}
# 呼叫函數
say_hello "使用者"
# 取得函數回傳值
SUM = $( add_numbers 10 20)
echo "總和: $SUM "
函數中的區域變數 1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
GLOBAL_VAR = "全域變數"
my_function() {
local LOCAL_VAR = "區域變數"
echo "函數內: $LOCAL_VAR "
echo "函數內存取全域: $GLOBAL_VAR "
}
my_function
echo "函數外: $GLOBAL_VAR "
# echo $LOCAL_VAR # 這會是空的
輸入輸出重導向 基本重導向 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# 標準輸出重導向到檔案(覆蓋)
echo "這是測試內容" > output.txt
# 標準輸出重導向到檔案(附加)
echo "附加的內容" >> output.txt
# 標準錯誤重導向
ls /nonexistent 2> error.log
# 同時重導向標準輸出和錯誤
command > output.txt 2>& 1
# 使用 /dev/null 丟棄輸出
command > /dev/null 2>& 1
Here Document 1
2
3
4
5
6
7
#!/bin/bash
cat << EOF > config.txt
伺服器設定檔
主機名稱: $(hostname)
日期: $(date)
使用者: $USER
EOF
管道操作 1
2
3
4
5
6
#!/bin/bash
# 使用管道串接命令
ps aux | grep nginx | awk '{print $2}'
# 計算檔案行數
cat /etc/passwd | wc -l
錯誤處理 檢查命令執行結果 1
2
3
4
5
6
7
8
9
10
#!/bin/bash
# 使用 $? 檢查
apt update
if [ $? -ne 0 ] ; then
echo "更新失敗" >& 2
exit 1
fi
# 使用 || 和 && 運算子
mkdir /tmp/mydir && echo "目錄建立成功" || echo "目錄建立失敗"
set 指令選項 1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# 遇到錯誤立即退出
set -e
# 使用未定義變數時報錯
set -u
# 管道中任一命令失敗則整體失敗
set -o pipefail
# 常用組合
set -euo pipefail
trap 捕捉訊號 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# 清理函數
cleanup() {
echo "執行清理工作..."
rm -f /tmp/tempfile_$$
exit
}
# 捕捉退出訊號
trap cleanup EXIT INT TERM
# 建立暫存檔案
echo "測試" > /tmp/tempfile_$$
echo "腳本執行中..."
sleep 5
常用範例腳本 系統資訊腳本 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
# system_info.sh - 顯示系統資訊
echo "========== 系統資訊 =========="
echo "主機名稱: $( hostname) "
echo "作業系統: $( lsb_release -d | cut -f2) "
echo "核心版本: $( uname -r) "
echo "目前時間: $( date '+%Y-%m-%d %H:%M:%S' ) "
echo ""
echo "========== 硬體資訊 =========="
echo "CPU: $( grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2) "
echo "記憶體: $( free -h | awk '/^Mem:/ {print $2}' ) "
echo "磁碟使用率:"
df -h | grep '^/dev'
echo ""
echo "========== 網路資訊 =========="
echo "IP 位址:"
ip -4 addr show | grep inet | awk '{print $2}'
備份腳本 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
# backup.sh - 自動備份腳本
set -euo pipefail
# 設定變數
BACKUP_DIR = "/backup"
SOURCE_DIR = "/var/www"
DATE = $( date +%Y%m%d_%H%M%S)
BACKUP_FILE = "backup_ ${ DATE } .tar.gz"
# 檢查備份目錄
[ -d " $BACKUP_DIR " ] || mkdir -p " $BACKUP_DIR "
# 執行備份
echo "開始備份 $SOURCE_DIR ..."
tar -czf " ${ BACKUP_DIR } / ${ BACKUP_FILE } " " $SOURCE_DIR "
# 刪除 7 天前的備份
find " $BACKUP_DIR " -name "backup_*.tar.gz" -mtime +7 -delete
echo "備份完成: ${ BACKUP_DIR } / ${ BACKUP_FILE } "
日誌監控腳本 1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# log_monitor.sh - 監控日誌檔案
LOG_FILE = "/var/log/syslog"
KEYWORD = "error"
tail -f " $LOG_FILE " | while read line; do
if echo " $line " | grep -qi " $KEYWORD " ; then
echo "[警告] $( date '+%H:%M:%S' ) - 發現錯誤: $line "
# 可在此加入通知機制
fi
done
腳本除錯技巧 使用 -x 選項 1
2
3
4
5
6
#!/bin/bash -x
# 或在腳本中使用 set -x
set -x # 開啟除錯模式
echo "這行會顯示執行過程"
set +x # 關閉除錯模式
使用 -v 選項 1
2
3
#!/bin/bash -v
# 顯示腳本每一行內容
echo "Hello"
自訂除錯函數 1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
DEBUG = true
debug_log() {
if [ " $DEBUG " = true ] ; then
echo "[DEBUG] $( date '+%H:%M:%S' ) - $1 " >& 2
fi
}
debug_log "開始執行腳本"
# 執行其他操作
debug_log "腳本執行完成"
常用除錯技巧 使用 bash -n script.sh 檢查語法錯誤 使用 shellcheck script.sh 進行靜態分析 在關鍵位置加入 echo 輸出變數值 使用 trap 'echo "Line $LINENO"' DEBUG 追蹤執行位置 參考資料 透過本文的學習,你應該已經掌握了在 Ubuntu 22.04 上撰寫 Shell Script 的基本技能。建議從簡單的腳本開始練習,逐步挑戰更複雜的自動化任務。
Licensed under CC BY-NC-SA 4.0