首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

8 個實用 Shell 腳本範例:從輸入驗證到磁碟填充的系統管理技巧

     編輯:更多程式設計知識

Shell 腳本是 Linux/Unix 系統管理、自動化運維、資料處理的基石。掌握經典範例模式,能快速解決實際問題。本文精選 8 個實用腳本,涵蓋輸入驗證、數學運算、參數處理、檔案操作、磁碟管理、配置解析、正則驗證、備份策略,並解析關鍵語法與最佳實踐。

範例 1:輸入驗證 —— 判斷數字、字母或其他


#!/bin/bash
# 腳本: check_input.sh

read -p "請輸入數字、字母或其他: " input

case $input in
    [0-9])       echo "✓ 輸入為數字" ;;
    [a-zA-Z])    echo "✓ 輸入為字母" ;;
    *)           echo "✗ 輸入非預期類型,請重試" ;;
esac

關鍵點:case 模式匹配支援字符類 [0-9]、[a-zA-Z];*) 為預設分支。注意:單字符匹配,多字符需用 [0-9]* 或正則 =~。

範例 2:互動式平均分計算


#!/bin/bash
# 腳本: average.sh

SCORE=0
SUM=0
COUNT=0

while true; do
    read -p "請輸入分數 (0-100, q 結束): " SCORE
    
    # 退出條件
    [[ "$SCORE" == "q" || "$SCORE" == "Q" ]] && break
    
    # 數值驗證
    if ! [[ "$SCORE" =~ ^[0-9]+$ ]] || (( SCORE < 0 || SCORE > 100 )); then
        echo "✗ 輸入無效,請輸入 0-100 的整數"
        continue
    fi
    
    (( SUM += SCORE ))
    (( COUNT++ ))
    AVG=$(( SUM / COUNT ))
    echo "當前平均: $AVG (共 $COUNT 筆)"
done

echo "最終平均: $AVG"
echo "程式結束"

關鍵點:(( ... )) 算術擴展支援 C 風格運算;[[ ... ]] 條件判斷支援正則 =~;read -p 合併提示與讀取。

範例 3:參數遞減輸出 —— shift 實戰


#!/bin/bash
# 腳本: shift_demo.sh
# 用法: ./shift_demo.sh a b c d e

echo "參數總數: $#"
echo "所有參數: $*"

while (( $# > 0 )); do
    echo "剩餘參數: $*"
    shift  # 移除 $1,所有參數左移
done

執行結果:


$ ./shift_demo.sh a b c d e
參數總數: 5
所有參數: a b c d e
剩餘參數: a b c d e
剩餘參數: b c d e
剩餘參數: c d e
剩餘參數: d e
剩餘參數: e

應用場景:處理不定數量位置參數、解析命令列選項 (配合 case $1 in)。

範例 4:檔案添加前綴 —— 讀取清單批量處理


#!/bin/bash
# 腳本: add_prefix.sh
# 準備: namelist.txt 每行一個名字

INPUT_FILE="namelist.txt"
PREFIX="USER_"

if [[ ! -f "$INPUT_FILE" ]]; then
    echo "✗ 找不到 $INPUT_FILE"
    exit 1
fi

while IFS= read -r name; do
    # 跳過空行與註解
    [[ -z "$name" || "$name" =~ ^# ]] && continue
    echo "${PREFIX}${name}"
done < "$INPUT_FILE"

關鍵點:while IFS= read -r line; done < file 是讀取檔案每行的標準模式,保留前導/尾隨空格、不解析反斜線。IFS= 防止欄位分割。

範例 5:批量檢測檔案是否存在


#!/bin/bash
# 腳本: check_files.sh

for file in test*.sh; do
    # 避免無匹配時字面字串 "test*.sh"
    [[ -e "$file" ]] || continue
    echo "✓ 存在: $file"
done

# 進階: 檢查指定清單
FILE_LIST=("config.yaml" "app.log" "data.csv" "backup.tar.gz")
for f in "${FILE_LIST[@]}"; do
    if [[ -f "$f" ]]; then
        echo "✓ 檔案存在: $f"
    else
        echo "✗ 檔案缺失: $f"
    fi
done

注意:for file in pattern 無匹配時會字面迭代模式字串,需 [[ -e "$file" ]] || continue 過濾。

範例 6:磁碟填充測試 —— 壓力測試與監控


#!/bin/bash
# 腳本: fill_disk.sh
# ⚠️ 僅用於測試環境,謹慎使用!

TARGET_DIR="/tmp/fill_test"
MAX_FILES=3800
FILE_SIZE_MB=1
COUNTER=0

mkdir -p "$TARGET_DIR"

# 建立 1MB 測試檔
dd if=/dev/zero of="$TARGET_DIR/testfile" bs=1M count=$FILE_SIZE_MB 2>/dev/null

while (( COUNTER < MAX_FILES )); do
    (( COUNTER++ ))
    
    # 每 1000 個報告進度
    if (( COUNTER % 1000 == 0 )); then
        echo "[$(date)] 已建立 $COUNTER 個檔案"
    fi
    
    cp "$TARGET_DIR/testfile" "$TARGET_DIR/file_${COUNTER}.dat" 2>/dev/null || {
        echo "✗ 磁碟空間不足,停止於 $COUNTER"
        break
    }
done

echo "完成,共建立 $COUNTER 個檔案"
# 清理: rm -rf "$TARGET_DIR"

關鍵點:dd 建立固定大小檔案;cp 複製比重複 dd 快;錯誤輸出導向 /dev/null;|| { ... } 處理失敗情況。

範例 7:配置檔解析 —— 逐行讀入陣列


#!/bin/bash
# 腳本: parse_config.sh
# 配置檔: hosts.allow 每行一個 IP

CONFIG_FILE="hosts.allow"
declare -a HOSTS
INDEX=0

# 讀取每行到陣列
while IFS= read -r line; do
    [[ -z "$line" || "$line" =~ ^# ]] && continue
    HOSTS[INDEX]="$line"
    (( INDEX++ ))
done < "$CONFIG_FILE"

# 遍歷陣列 (注意索引從 0 開始)
for (( i=0; i<${#HOSTS[@]}; i++ )); do
    echo "允許主機 [$i]: ${HOSTS[i]}"
done

echo "共讀取 ${#HOSTS[@]} 條記錄"

關鍵點:declare -a 宣告陣列;${#ARR[@]} 獲取長度;${ARR[i]} 存取元素。Bash 陣列索引從 0 開始。

範例 8:正則驗證與日期備份

8.1 正則驗證 6 位英數字


#!/bin/bash
# 腳本: validate.sh

REGEX='^[A-Za-z0-9]{6}$'

if [[ $1 =~ $REGEX ]]; then
    echo "✓ 驗證通過: $1"
    exit 0
else
    echo "✗ 驗證失敗: 輸入必須為 6 位英數字"
    exit 1
fi

8.2 日期命名備份腳本


#!/bin/bash
# 腳本: backup.sh

DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="/backup/backup_${DATE}.tar.gz"
SRC_DIRS="/home /etc /var/www"

echo "開始備份至 $BACKUP_FILE ..."
tar -czf "$BACKUP_FILE" $SRC_DIRS 2>/dev/null

if [[ $? -eq 0 ]]; then
    echo "✓ 備份成功: $BACKUP_FILE"
    # 可選: 刪除 7 天前備份
    find /backup -name "backup_*.tar.gz" -mtime +7 -delete
else
    echo "✗ 備份失敗"
    exit 1
fi

關鍵修正:原文 tar xcvf 為解壓縮參數,備份應用 tar -czf (建立、gzip、檔案)。

Shell 腳本最佳實踐總結

原則做法
Shebang固定使用 #!/bin/bash (或 #!/usr/bin/env bash 跨平台)
錯誤處理開頭加 set -euo pipefail (變數未設定報錯、命令失敗退出、管道失敗傳遞)
變數引用總是雙引號 "$VAR" 防止分詞與展開
迴圈讀檔標準模式 while IFS= read -r line; do ... done < file
算術運算使用 (( ... )) 或 $(( ... ))
條件判斷優先 [[ ... ]] (支援正則、模式匹配、邏輯運算)
函數化將邏輯封裝為函數,主流程清晰
日誌輸出統一 log_info()/log_error() 函數,含時間戳
臨時檔案使用 mktemp,退出時 trap 'rm -f $TMP' EXIT 清理
測試驗證使用 shellcheck 靜態分析,bats 單元測試

總結

這 8 個腳本涵蓋了 Shell 程式設計的核心模式:輸入處理、迴圈控制、參數操作、檔案遍歷、資源壓測、配置解析、正則驗證、備份自動化。理解每個範例背後的語法機制 (case/shift/read/for/while/[[ =~ ]]/陣列/date/tar),並遵循最佳實踐 (set -euo pipefail、雙引號變數、標準讀檔模式),就能將這些模板快速適配到實際運維、部署、監控、資料處理任務中。Shell 的威力在於無處不在、零依賴、直呼系統介面,掌握它是每個後端工程師、運維工程師的必修課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved