最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux?Shell腳本之流程控制語句舉例詳解

 更新時間:2026年06月16日 09:12:41   作者:IvanCodes  
流程控制是Shell腳本編程中非常重要的一部分,它允許我們根據(jù)條件執(zhí)行不同的操作或控制腳本的執(zhí)行流程,這篇文章主要介紹了Linux?Shell腳本之流程控制語句的相關(guān)資料,需要的朋友可以參考下

在掌握了Shell腳本的變量與運算之后,流程控制是構(gòu)建復(fù)雜和實用腳本的關(guān)鍵。它允許腳本根據(jù)不同的條件來選擇執(zhí)行路徑,或重復(fù)執(zhí)行特定任務(wù),從而實現(xiàn)腳本的靈活性與自動化。

思維導(dǎo)圖

一、條件判斷

if 語句是最基本的條件控制結(jié)構(gòu),它評估一個命令的退出狀態(tài)碼 (exit code)。如果退出碼為 0 (成功),則條件為真;如果為非 0 (失敗),則條件為假。

if 的基本結(jié)構(gòu)

格式:

if [ 條件判斷 ]; then
  # 條件為真時執(zhí)行的代碼塊
fi

代碼示例:檢查文件是否存在

#!/bin/bash
TARGET_FILE="/etc/hosts"

if [ -f "$TARGET_FILE" ]; then
  echo "文件 '$TARGET_FILE' 存在。"
fi

if...else 結(jié)構(gòu)

格式:

if [ 條件判斷 ]; then
  # 條件為真時執(zhí)行的代碼塊
else
  # 條件為假時執(zhí)行的代碼塊
fi

代碼示例:判斷目錄是否存在

#!/bin/bash
TARGET_DIR="/var/log/non_existent_dir"

if [ -d "$TARGET_DIR" ]; then
  echo "目錄 '$TARGET_DIR' 存在。"
else
  echo "目錄 '$TARGET_DIR' 不存在,將嘗試創(chuàng)建。"
  mkdir -p "$TARGET_DIR"
fi

if...elif...else 結(jié)構(gòu)

格式:

if [ 條件1 ]; then
  # 條件1為真時執(zhí)行
elif [ 條件2 ]; then
  # 條件1為假,但條件2為真時執(zhí)行
else
  # 以上所有條件都為假時執(zhí)行
fi

代碼示例:根據(jù)HTTP狀態(tài)碼判斷響應(yīng)

#!/bin/bash
HTTP_CODE=200

if [ $HTTP_CODE -eq 200 ]; then
  echo "請求成功 (OK)"
elif [ $HTTP_CODE -eq 404 ]; then
  echo "資源未找到 (Not Found)"
elif [ $HTTP_CODE -eq 500 ]; then
  echo "服務(wù)器內(nèi)部錯誤 (Internal Server Error)"
else
  echo "收到未知的HTTP狀態(tài)碼: $HTTP_CODE"
fi

條件判斷的實現(xiàn):test 和 [ ]

在Shell中,if 后的條件通常由 test 命令或其等價形式 [ ... ] 來實現(xiàn)。[[ ... ]][ ... ] 的擴展版本,提供了更多功能 (如模式匹配、邏輯與/或)。

常見判斷類型:

文件測試: -f (是普通文件?), -d (是目錄?), -e (存在?), -s (大小非0?), -r (可讀?), -w (可寫?), -x (可執(zhí)行?) 字符串比較: "$str1" = "$str2", "$str1" != "$str2", -z "$str" (字符串為空?), -n "$str" (字符串非空?) 整數(shù)比較: -eq (等于), -ne (不等于), -gt (大于), -ge (大于等于), -lt (小于), -le (小于等于)

二、循環(huán)結(jié)構(gòu)

循環(huán)用于重復(fù)執(zhí)行一段代碼,直到滿足某個退出條件。

for 循環(huán)

for 循環(huán)擅長遍歷一個列表 (字符串、文件名、數(shù)字序列等) 或進行C語言風(fēng)格的數(shù)值循環(huán)。

格式 (遍歷列表):

for variable_name in item1 item2 item3 ...; do
  # 循環(huán)體
done

代碼示例 (遍歷并重命名文件):

#!/bin/bash
# 將所有 .txt 文件重命名為 .txt.bak
for filename in *.txt; do
  if [ -f "$filename" ]; then
    echo "正在備份: $filename -> ${filename}.bak"
    mv "$filename" "${filename}.bak"
  fi
done

格式 (C風(fēng)格數(shù)值循環(huán)):

for (( initialization; condition; step )); do
  # 循環(huán)體
done

代碼示例 (執(zhí)行三次ping測試):

#!/bin/bash
TARGET_HOST="8.8.8.8"

for (( i=1; i<=3; i++ )); do
  echo "--- 第 $i 次 PING 測試 ---"
  ping -c 1 "$TARGET_HOST"
done

while 循環(huán)

while 循環(huán)在每次迭代前檢查條件,只要條件為真,就繼續(xù)執(zhí)行循環(huán)體。

格式:

while [ 條件判斷 ]; do
  # 循環(huán)體
done

代碼示例:逐行讀取文件

#!/bin/bash
CONFIG_FILE="/etc/fstab"

while read -r line; do
  # 忽略注釋和空行
  if [[ "$line" =~ ^# || -z "$line" ]]; then
    continue
  fi
  echo "讀取到配置行: $line"
done < "$CONFIG_FILE"

until 循環(huán)

until 循環(huán)與 while 邏輯相反:只要條件為假,就繼續(xù)執(zhí)行循環(huán)體,直到條件變?yōu)檎娌磐V埂?/p>

格式:

until [ 條件判斷 ]; do
  # 循環(huán)體
done

代碼示例:等待服務(wù)端口啟動

#!/bin/bash
PORT=8080
TIMEOUT=10
COUNT=0

until nc -z localhost $PORT >/dev/null 2>&1; do
  if [ $COUNT -ge $TIMEOUT ]; then
    echo "等待端口 $PORT 超時!"
    exit 1
  fi
  echo "端口 $PORT 尚未啟動,等待1秒..."
  sleep 1
  COUNT=$((COUNT + 1))
done

echo "端口 $PORT 已成功啟動!"

循環(huán)控制:break 和 continue

  • break: 立即從當前循環(huán)中完全跳出。
  • continue: 跳過當前循環(huán)的剩余部分,直接開始下一次迭代。

代碼示例:在循環(huán)中處理文件

#!/bin/bash
for file in /var/log/*; do
  if [ -d "$file" ]; then
    continue # 如果是目錄,則跳過
  fi

  echo "正在處理文件: $file"

  if [ -s "$file" ] && grep -q "ERROR" "$file"; then
    echo "在文件 '$file' 中找到錯誤,停止處理。"
    break # 找到錯誤后,完全停止
  fi
done

三、分支選擇

case 語句提供了一種更清晰的方式來處理多重條件分支,是 if...elif...else 的一種替代方案,特別適合基于單個變量的值進行匹配。

格式:

case $variable in
  pattern1)
    # 匹配 pattern1 時執(zhí)行
    ;;
  pattern2|pattern3)
    # 匹配 pattern2 或 pattern3 時執(zhí)行
    ;;
  *)
    # 默認情況,當以上模式都不匹配時執(zhí)行
    ;;
esac

代碼示例:腳本參數(shù)解析

#!/bin/bash
ACTION=$1

case $ACTION in
  start)
    echo "正在啟動服務(wù)..."
    # systemctl start my_service
    ;;
  stop)
    echo "正在停止服務(wù)..."
    # systemctl stop my_service
    ;;
  status)
    echo "檢查服務(wù)狀態(tài)..."
    # systemctl status my_service
    ;;
  *)
    echo "用法: $0 {start|stop|status}"
    exit 1
    ;;
esac

練習(xí)題

題目:

  1. 文件權(quán)限檢查:寫一個腳本,接收一個文件名作為參數(shù) ($1)。腳本需要判斷當前用戶對該文件是否同時擁有讀、寫、執(zhí)行權(quán)限。如果同時擁有,打印 "Full permissions granted";否則打印 "Permissions incomplete"。
  2. 字符串與邏輯判斷:寫一個腳本,檢查變量 ENVIRONMENT 的值。如果值是 production 并且 變量 FORCE_DEPLOY 的值不是 true,則打印 "Safety check passed: Not a forced production deploy." 并退出;否則,打印 "Proceeding with deployment."。
  3. C風(fēng)格 for 循環(huán)與算術(shù):使用C風(fēng)格的 for 循環(huán),打印出從10到20之間所有的偶數(shù) (包括10和20)。
  4. for 循環(huán)與通配符:寫一個腳本,查找 /var/log 目錄下所有以 .log 結(jié)尾的非空文件,并打印出它們的文件名。
  5. while 循環(huán)讀取標準輸入:寫一個腳本,持續(xù)讀取用戶從鍵盤輸入的內(nèi)容,直到用戶輸入 quit 為止。對于非 quit 的輸入,腳本應(yīng)該將其回顯到屏幕上。
  6. until 循環(huán)與命令退出碼grep 命令在找到匹配項時退出碼為0,找不到時為1。寫一個 until 循環(huán),每隔2秒檢查一次系統(tǒng)日志 (/var/log/messagesjournalctl -f 的輸出,為簡化可檢查一個普通文件) 是否出現(xiàn)了 "critical error" 字符串,一旦出現(xiàn)就打印 "Critical error detected!" 并退出。
  7. 嵌套循環(huán)與 break n:寫一個嵌套循環(huán)。外層循環(huán)從1到3,內(nèi)層循環(huán)從1到3。在內(nèi)層循環(huán)中,如果內(nèi)外兩個循環(huán)變量 (ij) 相等,則同時跳出內(nèi)外兩層循環(huán)。每次循環(huán)都打印當前的 ij 的值。
  8. case 語句與通配符:寫一個 case 語句,判斷一個文件名變量 FILENAME 的文件類型。如果文件名以 .log 結(jié)尾,打印 "Log file";如果以 .tar.gz.tgz 結(jié)尾,打印 "Compressed archive";如果以 .sh 結(jié)尾,打印 "Shell script";其他情況打印 "Unknown file type"。
  9. select 菜單 (高級)select 是一個特殊的循環(huán)結(jié)構(gòu),用于創(chuàng)建交互式菜單。寫一個腳本,使用 select 讓用戶從 "Start", "Stop", "Restart", "Exit" 四個選項中選擇一個操作,并根據(jù)用戶的選擇打印相應(yīng)的信息。當用戶選擇 "Exit" 時,腳本退出。

答案與解析:

  1. 文件權(quán)限檢查:
#!/bin/bash
if [ -z "$1" ]; then
  echo "用法: $0 <文件名>"
  exit 1
fi

if [ -r "$1" ] && [ -w "$1" ] && [ -x "$1" ]; then
  echo "Full permissions granted"
else
  echo "Permissions incomplete"
fi
  • 解析: if 語句中的 -r, -w, -x 是文件測試操作符,分別檢查讀、寫、執(zhí)行權(quán)限。&& 是邏輯與操作符,要求所有條件都為真才執(zhí)行 then 塊。
  1. 字符串與邏輯判斷:
#!/bin/bash
ENVIRONMENT="production"
FORCE_DEPLOY="false"

if [[ "$ENVIRONMENT" == "production" && "$FORCE_DEPLOY" != "true" ]]; then
  echo "Safety check passed: Not a forced production deploy."
  exit 0
else
  echo "Proceeding with deployment."
fi
  • 解析: 使用了 [[ ... ]] 擴展測試,它內(nèi)部支持 && (邏輯與) 和 != (字符串不等于) 操作符,語法更自然。
  1. C風(fēng)格 for 循環(huán)與算術(shù):
#!/bin/bash
for (( num=10; num<=20; num+=2 )); do
  echo $num
done
  • 解析: C風(fēng)格的 for 循環(huán)通過初始化 num=10,條件 num<=20,以及步進 num+=2 來精確控制循環(huán),直接打印出范圍內(nèi)的偶數(shù)。
  1. for 循環(huán)與通配符:
#!/bin/bash
for logfile in /var/log/*.log; do
  if [ -s "$logfile" ]; then
    echo "找到非空日志文件: $(basename "$logfile")"
  fi
done
  • 解析: *.log 是一個通配符,for 循環(huán)會遍歷所有匹配的文件名。-s 文件測試操作符用于判斷文件大小是否大于零。basename 命令用于提取文件名,去除路徑。
  1. while 循環(huán)讀取標準輸入:
#!/bin/bash
echo "請輸入內(nèi)容 (輸入 'quit' 退出):"
while read -r input_line; do
  if [ "$input_line" == "quit" ]; then
    break
  fi
  echo "你輸入了: $input_line"
done
  • 解析: while read -r input_line 是讀取標準輸入的標準模式。循環(huán)會一直持續(xù),直到 read 命令失敗 (例如,用戶按下Ctrl+D) 或遇到 break
  1. until 循環(huán)與命令退出碼:
#!/bin/bash
LOG_FILE_TO_CHECK="my_app.log"
touch $LOG_FILE_TO_CHECK # 創(chuàng)建一個空文件用于測試

echo "正在監(jiān)控 '$LOG_FILE_TO_CHECK' ..."
# 在另一個終端執(zhí)行 echo "critical error" >> my_app.log 來觸發(fā)
until grep -q "critical error" "$LOG_FILE_TO_CHECK"; do
  sleep 2
done

echo "Critical error detected!"
  • 解析: until 循環(huán)的條件是命令本身 (grep -q ...)。只要 grep 找不到字符串 (退出碼非0,條件為假),循環(huán)就繼續(xù)。一旦找到 (退出碼為0,條件為真),循環(huán)終止。
  1. 嵌套循環(huán)與 break n
#!/bin/bash
for (( i=1; i<=3; i++ )); do
  echo "外層循環(huán): i=$i"
  for (( j=1; j<=3; j++ )); do
    echo "  內(nèi)層循環(huán): j=$j"
    if [ $i -eq $j ]; then
      echo "  i 等于 j,跳出所有循環(huán)!"
      break 2 # '2' 表示跳出兩層循環(huán)
    fi
  done
done
  • 解析: break n 命令可以跳出指定層數(shù)的循環(huán)。break 1 (或 break) 只跳出當前層,break 2 跳出當前層和其外一層。
  1. case 語句與通配符:
#!/bin/bash
FILENAME="archive-2023.tar.gz"

case $FILENAME in
  *.log)
    echo "Log file"
    ;;
  *.tar.gz|*.tgz)
    echo "Compressed archive"
    ;;
  *.sh)
    echo "Shell script"
    ;;
  *)
    echo "Unknown file type"
    ;;
esac
  • 解析: case 語句的模式支持通配符,如 * (匹配任意字符序列)。| 用于分隔多個模式,表示“或”。
  1. select 菜單:
#!/bin/bash
PS3="請選擇一個操作 (輸入數(shù)字): "
options=("Start" "Stop" "Restart" "Exit")

select opt in "${options[@]}"; do
  case $opt in
    "Start")
      echo "正在啟動..."
      ;;
    "Stop")
      echo "正在停止..."
      ;;
    "Restart")
      echo "正在重啟..."
      ;;
    "Exit")
      echo "退出腳本。"
      break
      ;;
    *)
      echo "無效選項 '$REPLY',請重新選擇。"
      ;;
  esac
done
  • 解析: select 會自動生成一個帶編號的菜單。用戶的輸入編號會被翻譯成對應(yīng)的選項值 (賦給變量opt),而原始輸入則保存在 $REPLY 中。

總結(jié) 

到此這篇關(guān)于Linux Shell腳本之流程控制語句舉例詳解的文章就介紹到這了,更多相關(guān)Linux Shell流程控制語句內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

招远市| 武义县| 洞头县| 福清市| 山东省| 芮城县| 鹤峰县| 罗江县| 德昌县| 汉源县| 伊吾县| 叶城县| 眉山市| 厦门市| 历史| 洛南县| 高邮市| 白河县| 郑州市| 文安县| 安康市| 县级市| 百色市| 黄大仙区| 古浪县| 许昌市| 汝城县| 汉源县| 哈密市| 南安市| 西林县| 浪卡子县| 屏南县| 墨竹工卡县| 深泽县| 平果县| 开远市| 武安市| 太仆寺旗| 汉阴县| 华阴市|