)
Shell 判斷與循環(huán)語句詳解一、判斷語句1.if語句基本語法if[條件];then# 條件為真時執(zhí)行fi完整語法if[條件1];then# 條件1為真elif[條件2];then# 條件2為真else# 都不滿足fi示例#!/bin/bashread-p請輸入分數(shù): scoreif[$score-ge90];thenecho優(yōu)秀elif[$score-ge60];thenecho及格elseecho不及格fi嵌套 ifif[條件1];thenif[條件2];thenecho條件1和條件2都滿足fifi2.case語句語法case$變量in模式1)命令;;模式2|模式3)命令;;*)默認命令;;esac示例#!/bin/bashread-p請輸入 yes/no: answercase$answerinyes|Y|y)echo你選擇了是;;no|N|n)echo你選擇了否;;*)echo輸入無效;;esac服務(wù)管理腳本示例#!/bin/bashcase$1instart)systemctl start nginx;;stop)systemctl stop nginx;;restart)systemctl restart nginx;;status)systemctl status nginx;;*)echo用法:$0{start|stop|restart|status}exit1;;esac3. 條件測試3.1 數(shù)值比較運算符含義-eq等于-ne不等于-gt大于-lt小于-ge大于等于-le小于等于if[$a-gt$b];thenechoa bfi3.2 字符串比較運算符含義或相等!不相等-z為空-n非空if[$namezzw];thenecho匹配fiif[-z$name];thenechoname 為空fi3.3 文件測試運算符含義-e存在-f是普通文件-d是目錄-r可讀-w可寫-x可執(zhí)行-s非空-L是符號鏈接if[-f/etc/passwd];thenecho文件存在fiif[-d/var/log];thenecho目錄存在fi3.4 邏輯運算運算[ ][[ ]]與-a或-o||非!!# [ ][-f$file-a-r$file]echo存在且可讀# [[ ]][[-f$file-r$file]]echo存在且可讀二、循環(huán)語句1.for循環(huán)語法一列表遍歷for變量in列表;do命令done示例foriin12345;doecho$idonefornameinalice bob charlie;doechoHello,$namedone語法二范圍foriin{1..10};doecho$idoneforiin{1..10..2};do# 步長 2echo$idone語法三C 風(fēng)格for((i1;i10;i));doecho$idone語法四遍歷文件forfilein*.txt;doecho處理:$filedone語法五遍歷命令輸出foruserin$(cat/etc/passwd|cut-d:-f1);doecho用戶:$userdone實戰(zhàn)批量創(chuàng)建用戶#!/bin/bashforuserinuser1 user2 user3;doifid$user/dev/null;thenecho$user已存在elseuseradd$userecho123456|passwd--stdin$userecho$user創(chuàng)建成功fidone2.while循環(huán)語法while[條件];do命令done條件為真時循環(huán)為假時退出。示例#!/bin/bashi1while[$i-le5];doecho$i((i))done讀取文件#!/bin/bashwhilereadline;doecho行:$linedonefile.txt無限循環(huán)whiletrue;doecho按 CtrlC 退出sleep1done實戰(zhàn)監(jiān)控服務(wù)狀態(tài)#!/bin/bashwhiletrue;doif!systemctl is-active--quietnginx;thenecho$(date): nginx 掛了重啟中...systemctl restart nginxfisleep10done3.until循環(huán)語法until[條件];do命令done和while相反條件為假時循環(huán)為真時退出。示例#!/bin/bashi1until[$i-gt5];doecho$i((i))done等價于i1while[$i-le5];doecho$i((i))done4.break和continuebreak跳出循環(huán)foriin{1..10};doif[$i-eq5];thenbreak# 到 5 就退出fiecho$idone# 輸出1 2 3 4continue跳過本次foriin{1..5};doif[$i-eq3];thencontinue# 跳過 3fiecho$idone# 輸出1 2 4 5break N跳出多層循環(huán)foriin{1..3};doforjin{1..3};doif[$j-eq2];thenbreak2# 跳出兩層fiecho$i-$jdonedone5.select循環(huán)語法select變量in列表;do命令done自動生成菜單用戶選擇后執(zhí)行。示例#!/bin/bashPS3請選擇操作: selectoptinstart stop restart status quit;docase$optinstart)echo啟動服務(wù);;stop)echo停止服務(wù);;restart)echo重啟服務(wù);;status)echo查看狀態(tài);;quit)break;;*)echo無效選擇;;esacdone運行效果1) start 2) stop 3) restart 4) status 5) quit 請選擇操作:三、實戰(zhàn)綜合示例1. 批量 Ping 測試#!/bin/bashforipin10.1.8.{1..254};doping-c1-W1$ip/dev/nullecho$ip在線donewait2. 磁盤監(jiān)控告警#!/bin/bashTHRESHOLD80df-h|grep-vFilesystem|whilereadline;dousage$(echo$line|awk{print $5}|seds/%//)mount$(echo$line|awk{print $6})if[$usage-gt$THRESHOLD];thenecho警告:$mount使用率$usage%fidone3. 自動備份腳本#!/bin/bashBACKUP_DIR/backupDATE$(date%Y%m%d)SOURCE/var/wwwfordirin$SOURCE/*;doif[-d$dir];thenname$(basename$dir)tar-czvf${BACKUP_DIR}/${name}_${DATE}.tar.gz$dirif[$?-eq0];thenecho備份成功:$nameelseecho備份失敗:$namefifidone# 刪除 7 天前的備份find$BACKUP_DIR-name*.tar.gz-mtime7-delete4. 服務(wù)健康檢查#!/bin/bashSERVICESnginx mysql redisforsvcin$SERVICES;doifsystemctl is-active--quiet$svc;thenecho$svc: 運行中elseecho$svc: 已停止嘗試啟動...systemctl start$svcif[$?-eq0];thenecho$svc: 啟動成功elseecho$svc: 啟動失敗fifidone5. 用戶管理菜單#!/bin/bashPS3請選擇操作: selectoptin添加用戶刪除用戶查看用戶退出;docase$optin添加用戶)read-p請輸入用戶名: usernameifid$username/dev/null;thenecho用戶已存在elseuseradd$usernameecho用戶創(chuàng)建成功fi;;刪除用戶)read-p請輸入用戶名: usernameuserdel-r$username2/dev/nullecho刪除成功||echo刪除失敗;;查看用戶)cut-d:-f1/etc/passwd;;退出)break;;esacdone四、常見錯誤與注意事項錯誤說明正確寫法if[if和[之間沒空格if [[ $a $b ]變量沒加引號[ $a $b ][ $a x ][ ]中不標(biāo)準(zhǔn)[ $a x ]-o用在[[ ]][[ ]]不支持-o用||兩邊沒空格被當(dāng)成字符串[[ $a x ]]for i in {1..10}某些 Shell 不支持用$(seq 1 10)while read line不讀最后一行文件末尾無換行用while read line || [ -n $line ]五、一句話總結(jié)判斷if、case循環(huán)for、while、until、select控制break、continue結(jié)構(gòu)用途if條件判斷case多值匹配for遍歷列表while條件循環(huán)until反向條件循環(huán)select生成菜單break跳出循環(huán)continue跳過本次記住if和[之間有空格變量加引號[[ ]]比[ ]更安全。