【網絡運維】Shell 腳本編程:while 循環與 until 循環

Shell 腳本編程:while 循環與 until 循環

循環結構簡介

循環語句是 Shell 腳本中用于重復執行一條或一組指令的重要工具,直到滿足特定條件時停止執行。Shell 腳本中常見的循環語句包括 while、until、for 和 select。本文將重點介紹 while 和 until 兩種循環結構,并通過豐富的示例展示其實際應用場景。

while 循環與 until 循環語法解析

while 循環語法

while 循環屬于“當型”循環結構,其基本語法格式為:

while <條件表達式>
do指令...
done

執行邏輯

  • 首先判斷條件表達式是否成立
  • 如果成立,則執行循環體內的指令
  • 每次執行到 done 時重新判斷條件表達式
  • 直到條件不成立時退出循環

until 循環語法

until 循環屬于"直到型"循環結構,其基本語法格式為:

until <條件表達式>
do指令...
done

執行邏輯

  • 當條件表達式不成立時執行循環體
  • 直到條件表達式成立時終止循環

基礎應用示例

示例1:豎向打印數字

while 實現方式

#!/bin/bash
i=5
while ((i>0))  # 當i大于0時執行循環
doecho $i     # 打印當前i值((i--))     # i自減1
done

until 實現方式

#!/bin/bash
i=5
until ((i==0))  # 直到i等于0時停止循環
doecho $i       # 打印當前i值((i--))       # i自減1
done

示例2:計算1-100的累加和

#!/bin/bash
i=1
sum=0
while ((i<=100))    # 當i小于等于100時執行循環
do((sum+=i))        # 累加i到sum變量# let sum=sum+i   # 另一種累加方式((i++))           # i自增1# let i++         # 另一種自增方式
done
echo "1+2+3+...+99+100=$sum"  # 輸出結果

示例3:計算5的階乘

#!/bin/bash
i=1
sum=1
while ((i<=5))    # 循環5次
do((sum*=i))      # 累乘計算階乘((i++))         # i自增1
done
echo "5的階乘為:$sum"  # 輸出結果

示例4:猴子吃桃問題

問題描述

  • 猴子第一天摘下若干個桃子,當即吃了一半,還不過癮,又多吃了一個
  • 第二天早上又將第一天剩下的桃子吃掉一半,又多吃了一個
  • 以后每天早上都吃了前一天剩下的一半零一個
  • 到第10天早上想再吃時,發現只剩下一個桃子了

問:猴子第一天摘了多少個桃子?

while循環解法

#!/bin/bash
# 當天桃子數量,第10天為1
today=1
# 前一天桃子數量
lastday=0
# 只需要迭代9次(從第10天倒推回第1天)
i=1
while ((i<=9))
do# 計算上一天桃子數量:today = (lastday/2) - 1 → lastday = (today+1)*2lastday=$[(today+1)*2]# 把上一天的數量當作今天的數量,繼續向前推算today=${lastday}((i++))
done
echo "猴子第一天摘的桃子數量是:$today。"

函數遞歸解法

#!/bin/bash
function sum (){if [[ $1 = 1 ]];thenecho $1  # 第10天只剩1個桃子else# 遞歸計算:第n天的桃子數 = (第n+1天的桃子數 + 1) * 2echo $[ ($(sum $[$1 -1]) + 1)*2 ]fi
}
echo "猴子第一天摘的桃子數量是:$(sum 10)。"

示例5:猜數字游戲

#!/bin/bash
# 生成1-50的隨機數字
random_num=$[ RANDOM%50+1 ]
echo "${random_num}" >> /tmp/number  # 保存隨機數(用于調試)# 記錄猜測次數
i=0
while true  # 無限循環,直到猜對退出
doread -p "猜一猜系統產生的50以內隨機數是:" numif ((num>=1 && num<=50));then  # 驗證輸入有效性((i++))  # 增加猜測次數if [ $num -eq ${random_num} ];thenecho "恭喜你,第$i次猜對了!"rm -f /tmp/number  # 清理臨時文件exit  # 退出腳本elseecho -n "第$i次猜測,加油。"# 提供大小提示[ $num -gt ${random_num} ] && echo "太大了,往小猜。" || echo "太小了,往大猜。"fielseecho "請輸入一個介于1-50之間的數字。"fi 
done

腳本后臺運行與管理

后臺運行方法

在實際工作中,可能需要讓腳本在后臺持續運行:

  1. 使用 & 符號sh /server/scripts/while_01.sh &
  2. 使用 nohup 命令nohup /server/scripts/uptime.sh &
  3. 使用 screen 會話screen -S session_name 然后執行腳本

進程管理命令

  • sh whilel.sh &:后臺運行腳本
  • ctl+c:停止當前任務
  • ctl+z:暫停當前任務
  • bg:將任務放到后臺運行
  • fg:將任務調到前臺運行
  • jobs:查看當前任務
  • kill:終止指定任務

并發控制示例

示例:讓所有CPU滿負荷工作

#!/bin/bash
# 獲取CPU核心數量
cpu_count=$(lscpu|grep '^CPU(s)'|awk '{print $2}')
i=1
while ((i<=${cpu_count}))
do{while :  # 無限循環do((1+1))  # 簡單計算消耗CPUdone} &  # 放到后臺運行((i++))
done

注意事項

  • { command1; command2; ... } & 可以將多個命令放到后臺運行
  • {} 內部兩側需要有空格
  • 最后一個命令后需要有分號

使用wait等待后臺任務完成

#!/bin/bash
> /tmp/sleep  # 清空文件
i=1
while [ $i -le 10 ]
do# 每個任務睡眠i秒后寫入文件( sleep $i && echo sleep $i >> /tmp/sleep )&((i++))
done
wait  # 等待所有后臺任務完成
cat /tmp/sleep  # 顯示結果

實戰應用

示例1:監控系統負載

#!/bin/bash
while true  # 無限循環
douptime    # 顯示系統負載sleep 2   # 休眠2秒
done

后臺運行并記錄日志

#!/bin/bash
while true
douptime >> /tmp/loadaverage.log  # 追加到日志文件sleep 2
done# 后臺運行
bash while2.sh &

示例2:服務監控與自動重啟

while格式

#!/bin/bash
while true
do # 檢查sshd服務是否活躍systemctl is-active sshd.service &>/dev/nullif [ $? -ne 0 ];then  # 如果服務不活躍systemctl restart sshd.service  &>/dev/null  # 重啟服務fisleep 5  # 每5秒檢查一次
done

until格式

#!/bin/bash
until false  # 一直執行直到false(永遠不會發生)
do systemctl is-active sshd.service &>/dev/nullif [ $? -ne 0 ];then systemctl restart sshd.service  &>/dev/nullfisleep 5
done

示例3:網站可用性監控

#!/bin/bash# 參數檢查
if [ $# -ne 1 ];thenecho "Usage: $0 url"exit 1
fiurl="$1"while true
do# 使用curl檢查網站可用性if curl -o /dev/null -s --connect-timeout 5 $url;thenecho "$(date): $url is ok."  # 添加時間戳elseecho "$(date): $url is error."fisleep 3  # 每3秒檢查一次
done

示例4:簡易短信平臺模擬

#!/bin/bash# 初始化變量
money=0.5  # 默認金額
msg_file=/tmp/message  # 消息保存文件
> $msg_file  # 清空消息文件# 手機操作菜單
function print_menu () {cat << EOF
1. 查詢余額
2. 發送消息
3. 充值
4. 退出
EOF
}# 數字檢查函數
function check_digit () {expr $1 + 1 &> /dev/null && return 0 || return 1
}# 顯示余額函數
function check_money_all () {echo "余額為:$money 元。"
}# 檢查余額是否充足(每條短信0.15元)
function check_money () {# 將元轉換為分進行比較new_money=$(echo "$money*100"|bc|cut -d . -f1)if [ ${new_money} -lt 15 ];thenecho "余額不足,請充值。"return 1  # 余額不足elsereturn 0  # 余額充足fi
}# 充值函數
function chongzhi () {read -p "充值金額(單位:元):" chongzhi_moneywhile truedocheck_digit $chongzhi_moneyif [ $? -eq 0 ] && [ ${chongzhi_money} -ge 1 ];thenmoney=$( echo "($money+${chongzhi_money})"|bc)  # 使用bc進行浮點計算echo "當前余額為:$money 元"return 0elseread -p "重新輸入充值金額(至少1元):" chongzhi_money fidone
}# 發送消息函數
function send_msg () {check_money  # 檢查余額if [ $? -eq 0 ];then  # 余額充足read -p "請輸入消息內容:" messageecho "$(date): $message" >> ${msg_file}  # 保存消息帶時間戳# 計算新余額(每條消息0.15元)new_money=$(echo "scale=2;($money*100-15)" | bc |cut -d. -f1)if [ ${new_money} -ge 100 ];thenmoney=$(echo "scale=2;${new_money}/100" | bc )elsemoney=0$(echo "scale=2;${new_money}/100" | bc )fiecho "消息已發送,當前余額為:$money 元"fi
}# 主程序
while true
doprint_menuechoread -p "請輸入你的選擇:" choiceclearcase $choice in1)check_money_all;;2)send_msg;;3)chongzhi;;4)echo "感謝使用,再見!"exit;;*)echo "無效選擇,請從1、2、3、4中選擇。" ;;esacecho
done

while循環讀取文件的四種方式

以讀取 /etc/hosts 文件為例:

方式1:使用exec重定向

#!/bin/bash
exec < /etc/hosts  # 將文件重定向到標準輸入
while read line
doecho $line
done

方式2:使用管道

#!/bin/bash
cat /etc/hosts | while read line
doecho $line
done

方式3:使用輸入重定向

#!/bin/bash
while read line
doecho $line
done < /etc/hosts

方式4:設置IFS分隔符

#!/bin/bash
IFS=$'\n'  # 設置字段分隔符為換行符
for line in $(cat /etc/hosts)
doecho $line
done

實戰案例

案例1:防止DDoS攻擊 - Web日志分析

#!/bin/bash
logfile=$1  # 日志文件路徑參數while true
do# 提取IP并統計訪問次數awk '{print $1}' $logfile | grep -v "^$" | sort | uniq -c > /tmp/tmp.log# 處理統計結果exec < /tmp/tmp.logwhile read linedoip=$(echo $line | awk '{print $2}')  # 提取IPcount=$(echo $line | awk '{print $1}')  # 提取訪問次數# 如果訪問次數超過500且不在防火墻黑名單中if [ $count -gt 500 ] && [ $(iptables -L -n | grep "$ip" | wc -l) -lt 1 ];theniptables -I INPUT -s $ip -j DROP  # 封禁IPecho "$(date): $ip is dropped (PV: $count)" >> /tmp/droplist_$(date +%F).logfidonesleep 3600  # 每小時檢查一次
done

案例2:防止DDoS攻擊 - 網絡連接數監控

#!/bin/bash
while true
do# 統計ESTABLISHED狀態的連接并按IP分組ss -t | grep ESTAB | awk '{print $4}' | cut -d: -f1 | sort | uniq -c > /tmp/tmp.logexec < /tmp/tmp.logwhile read linedoip=$(echo $line | awk '{print $2}')count=$(echo $line | awk '{print $1}')# 如果單個IP連接數超過100且未被封禁if [ $count -gt 100 ] && [ $(iptables -L -n | grep "$ip" | wc -l) -lt 1 ];theniptables -I INPUT -s $ip -j DROPecho "$(date): $ip is dropped (連接數: $count)" >> /tmp/droplist_$(date +%F).logfidonesleep 10  # 每10秒檢查一次
done

總結

  1. while循環特點

    • 擅長執行守護進程和持續運行的應用
    • 適合處理頻率小于1分鐘的循環任務
    • 多數while循環可用for循環或cron定時任務替代
  2. 各語句使用場景

    • 條件表達式:簡短條件判斷(文件存在、字符串非空等)
    • if語句:不同值數量較少的條件判斷
    • for循環:常規循環處理的首選
    • while循環:守護進程、無限循環(需配合sleep控制頻率)
    • case語句:服務啟動腳本、固定規則字符串處理
    • select語句:菜單打印(較少使用,通常用here文檔替代)
  3. 函數的作用

    • 使代碼邏輯更加清晰
    • 減少重復代碼開發
    • 提高代碼可維護性

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94437.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94437.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94437.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LLM 中評價指標與訓練概要介紹

在【LLM】LLM 中增量解碼與模型推理解讀一文中對 LLM 常見名詞進行了介紹&#xff0c;本文會對 LLM 中評價指標與訓練概要進行介紹&#xff0c;本文并未介紹訓練實操細節&#xff0c;未來有機會再了解&#xff5e; 一、LLM 如何停止輸出 在看 LLM 評價指標前&#xff0c;先看…

Java 20 新特性及具體應用

目錄 1. 模式匹配 for switch&#xff08;預覽特性&#xff09; 2. 記錄模式&#xff08;預覽特性&#xff09; 3. 外部函數與內存 API&#xff08;預覽特性&#xff09; 4. 矢量 API&#xff08;孵化器特性&#xff09; 5. 作用域值&#xff08;預覽特性&#xff09; 6. …

【STM32】CubeMX(十一):FreeRTOS任務掛起與解掛

這篇文章是 STM32 HAL FreeRTOS 下的任務掛起與恢復機制&#xff0c; 結合 CubeMX 圖示與代碼&#xff0c;構建了一個 FreeRTOS 控制示例。 本篇目標&#xff1a;創建兩個任務&#xff1a; 一個控制藍燈閃爍&#xff08;myTask01&#xff09; 另一個監控按鍵&#xff08;Start…

圖片預加載:提升Web性能的關鍵

&#x1f90d; 前端開發工程師、技術日更博主、已過CET6 &#x1f368; 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 &#x1f560; 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》、《前端求職突破計劃》 &#x1f35a; 藍橋云課簽約作者、…

大模型壓縮三劍客:量化、剪枝與知識蒸餾全解析

在人工智能飛速發展的今天&#xff0c;大語言模型&#xff08;LLM&#xff09;如通義千問、GPT 等已成為推動智能應用的核心引擎。然而&#xff0c;這些模型動輒數十億甚至上千億參數&#xff0c;帶來了高昂的計算成本和部署門檻。如何在不顯著犧牲性能的前提下&#xff0c;讓大…

Seaborn數據可視化實戰:Seaborn基礎圖表繪制入門

基礎圖表繪制&#xff1a;Seaborn入門教程 學習目標 通過本課程的學習&#xff0c;你將掌握如何使用Seaborn庫繪制基礎圖表&#xff0c;包括條形圖、折線圖和散點圖。你將了解Seaborn的基本函數和參數設置&#xff0c;以及如何通過調整這些參數來優化圖表的視覺效果。 相關知識…

阿里開源通義萬相Wan2.2:視頻生成技術的革命性突破

在人工智能視頻生成領域,阿里云通義實驗室于2025年7月重磅開源了新一代視頻生成大模型 Wan2.2,其核心亮點包括人體動作生成的極致精度、電影級美學表達以及高效的資源利用效率,標志著視頻生成技術邁入了一個全新的階段。 一、核心功能:三大模型,覆蓋全場景視頻生成 Wan2.…

說說你對Integer緩存的理解?

大家好&#xff0c;我是鋒哥。今天分享關于【說說你對Integer緩存的理解?】面試題。希望對大家有幫助&#xff1b; 說說你對Integer緩存的理解? 超硬核AI學習資料&#xff0c;現在永久免費了&#xff01; Integer 緩存是 Java 中一個優化機制&#xff0c;它主要通過緩存一部…

高速CANFD收發器ASM1042在割草機器人輪轂電機通信系統中的適配性研究

摘要割草機器人輪轂電機的通信系統對其實現自主控制和高效作業至關重要。本文旨在研究國科安芯推出的高速CANFD收發器芯片ASM1042是否能夠滿足割草機器人輪轂電機通信系統的復雜需求。通過詳細分析輪轂電機通信系統的性能要求&#xff0c;以及ASM1042的電氣、功能和環境特性&am…

MTK Linux DRM分析(十二)- KMS Panel框架層(drm_panel.c、drm_mipi_dbi.c、drm_mipi_dsi.c)

一、簡介 三個代碼文件(drm_mipi_dbi.c、drm_panel.c、drm_mipi_dsi.c)的分析。這些文件都是Linux內核DRM(Direct Rendering Manager)子系統的組成部分,主要用于支持顯示面板,特別是通過MIPI(Mobile Industry Processor Interface)接口的顯示設備。它們提供了顯示驅動…

合合信息acge模型獲C-MTEB第一,文本向量化迎來新突破

前言&#xff1a; 在當今時代&#xff0c;大型語言模型以其驚人的發展速度和廣泛的應用前景&#xff0c;正成為全球科技界的矚目焦點。這些模型的強大能力&#xff0c;源自于背后默默支撐它們的Embedding技術——一種將語言轉化為機器可理解的數值向量的關鍵技術。隨著大型語言…

26.內置構造函數

2.內置構造函數2.1Object2.2Array2.3String2.4number

tauri配置允許執行eval腳本,在打包cocos游戲web/phone移動端的時候一定要配置

解決辦法&#xff1a;在tauriconfig中配置"csp": "default-src self asset: unsafe-inline customprotocol://* http://localhost:* ws:localhost:* unsafe-eval ipc: http://ipc.localhost; script-src unsafe-eval self https://www.googletagmanager.com uns…

K 均值聚類算法學習總結

一、聚類算法基礎認知 核心概念&#xff1a;聚類屬于無監督學習&#xff0c;核心是把 “相似的樣本” 自動分到同一組&#xff08;簇&#xff09;&#xff0c;不需要預先標注的標簽。主要挑戰是怎么定義 “相似性”、評估聚類效果以及確定最好的聚類數量。 距離度量&#xff1a…

基于Spring Cloud Gateway動態路由與灰度發布方案對比與實踐指導

基于Spring Cloud Gateway動態路由與灰度發布方案對比與實踐指導 一、問題背景介紹 在微服務架構中&#xff0c;API網關負責統一入口、路由分發與權限校驗功能。隨著業務需求的不斷演進&#xff0c;如何靈活地實現路由動態更新、版本灰度發布以及流量打點就成為運維和開發團隊的…

MySQL InnoDB Buffer Pool詳解:原理、配置與性能優化

1. 為什么需要 Buffer Pool&#xff1f;1.1 數據庫性能瓶頸分析在 MySQL 的運行過程中&#xff0c;最核心的性能瓶頸來自磁盤 IO。磁盤訪問延遲&#xff1a;一次機械硬盤 IO 操作可能需要數毫秒&#xff0c;即使是 SSD&#xff0c;訪問延遲也在幾十微秒量級。內存訪問延遲&…

ArcGIS Pro 安裝路徑避坑指南:從崩潰根源到規范實操(附問題修復方案)

作為 GIS 從業者&#xff0c;你是否遇到過這些糟心場景&#xff1a;ArcGIS Pro 雙擊啟動無響應、運行中突然彈出 “Runtime Error” 崩潰、加載矢量數據時提示 “找不到指定文件”&#xff1f;排查半天后發現&#xff0c;這些問題的 “元兇” 竟藏在安裝路徑里 —— 中文路徑或…

Python 實戰:內網滲透中的信息收集自動化腳本(2)

用途限制聲明&#xff0c;本文僅用于網絡安全技術研究、教育與知識分享。文中涉及的滲透測試方法與工具&#xff0c;嚴禁用于未經授權的網絡攻擊、數據竊取或任何違法活動。任何因不當使用本文內容導致的法律后果&#xff0c;作者及發布平臺不承擔任何責任。滲透測試涉及復雜技…

批量轉雙層PDF軟件:高效轉換,提升文檔管理效率

在文檔管理和信息檢索中&#xff0c;雙層PDF文件因其獨特的結構而備受青睞。雙層PDF文件不僅保留了原始文檔的外觀&#xff0c;還增加了對文檔內容進行搜索和選擇的功能&#xff0c;極大地提高了文檔管理和信息檢索的效率。批量轉雙層PDF軟件正是為了解決這一需求而設計的&…

rust語言 (1.88) egui (0.32.1) 學習筆記(逐行注釋)(七) 鼠標在控件上懸浮時的提示

文本提示on_hover_text ui.label("標簽").on_hover_text("這是一個標簽"); ui.text_edit_singleline(&mut edittext).on_hover_text("這是輸入框"); if ui.button("提交").on_hover_text("這是一個按鈕").clicked(){}提…