目錄
前言
數值型 for 循環
語法格式
示例:打印 1 到 5
示例:打印5次Hello World
示例:計算 1 到 100 的累加和
遍歷型 for 循環
語法格式
示例:遍歷字符串列表
示例:遍歷數組
示例:遍歷文件列表
示例:這邊會給一個IP地址的文件(ipddr.txt)需要 ping 文件中的IP(主機)判斷是否能通
示例:統計 /var/log 有多少個文件,并且顯示這些文件名
示例:需要ping 通 某個網段 ?機器 ?并且 輸出 通和不通 反饋結果
示例:九九乘法表
while循環
條件判斷型
典型示例
示例:實時監控httpd的運行狀態
基本語法
case循環
快速示例
實用技巧
示例:設置系統開機、關機和重啟
示例:用 case 編寫一個查看 ?cpu ? 內存 ?硬盤 資源使用情況
總結
前言
在信息化高速發展的今天,服務器與終端設備的穩定運行已成為企業業務連續性的命脈。面對日益復雜的系統環境,運維人員需要隨時掌握 CPU、磁盤、內存三大核心資源的實時狀態,以便在性能瓶頸或故障萌芽階段即可精準干預。然而,傳統命令行工具雖然功能強大,卻存在記憶負擔高、操作路徑長、輸出可讀性差等問題,極易在緊急排障時貽誤戰機。為此,我們設計了一款輕量級 Shell 交互腳本,將 top、df、free 等底層指令封裝成一鍵式菜單,既保留原生命令的詳盡數據,又通過友好提示與編號選擇顯著降低使用門檻。腳本遵循 POSIX 標準,兼容絕大多數 Linux 發行版,可直接運行于生產服務器、容器或虛擬機,真正做到了“開箱即用”。接下來,讓我們一起體驗它在日常巡檢中所帶來的效率躍升。
數值型 for 循環
語法格式
bash
復制
for ((初始值; 限制條件; 步長))
do循環體代碼
done
-
初始值:循環變量的初始值。
-
限制條件:循環繼續執行的條件。
-
步長:每次循環后循環變量的增量或減量。
示例:打印 1 到 5
bash
復制
#!/bin/bashfor ((i=1; i<=5; i++))
doecho "當前數字: $i"
done
輸出結果:
復制
當前數字: 1
當前數字: 2
當前數字: 3
當前數字: 4
當前數字: 5
示例:打印5次Hello World
# shell腳本
for ((i=0;i<5;i++))
doecho "$i - Hello World"
done# 測試
[root@localhost shelldemo]# sh dome8.sh
0 - Hello World
1 - Hello World
2 - Hello World
3 - Hello World
4 - Hello World
示例:計算 1 到 100 的累加和
bash
復制
#!/bin/bashcount=0
for((i=0;i<=100;i++))
docount=$(($count + $i));
doneecho "累加的結果是:${count}";# 測試
[root@localhost shelldemo]# sh dome9.sh
累加的結果是:5050
輸出結果:
1 到 10 的累加和為: 55
遍歷型 for 循環
語法格式
bash
復制
for 變量名 in 數據1 數據2 數據3 ...
do循環體代碼
done
-
變量名:依次取數據集合中的每個值。
-
數據集合:可以是顯式列出的數據,也可以是數組、命令輸出等。
示例:遍歷字符串列表
bash
復制
#!/bin/bashfor animal in cat dog elephant
doecho "動物名稱: $animal"
done
輸出結果:
復制
動物名稱: cat
動物名稱: dog
動物名稱: elephant
示例:遍歷數組
bash
復制
#!/bin/bashmy_array=(A B C D)for element in ${my_array[@]}
doecho "數組元素: $element"
done
輸出結果:
復制
數組元素: A
數組元素: B
數組元素: C
數組元素: D
示例:遍歷文件列表
bash
復制
#!/bin/bashfor file in $(ls /root/shelldemo)
doecho "文件名: $file"
done
輸出結果:
復制
文件名: file1.sh
文件名: file2.sh
文件名: file3.sh
示例:這邊會給一個IP地址的文件(ipddr.txt)需要 ping 文件中的IP(主機)判斷是否能通
# shell腳本
HT_IP=$(< ./ip.txt)
#for循環
for ip in $HT_IP
#ping
doping -c 3 -i 0.5 -W 2 $ip &>/dev/nullif [ $? -eq 0 ]; thenecho "$ip is up"elseecho "$ip is down"fi
#輸出結果
done# 測試
[root@localhost shelldemo]# sh dome10.sh
192.168.10.101 is up
192.168.10.102 is down
192.168.10.103 is down
192.168.10.104 is down
192.168.10.105 is down
192.168.10.106 is up
192.168.10.1 is up
示例:統計 /var/log 有多少個文件,并且顯示這些文件名
# shell腳本
# 將所有的文件列表用一個變量手記起來
file_list=$(ls -r /var/log/*);
count= 0
# for遍歷,判斷是否存在文件
for file in $file_list
# 如果存在的話,+1,并打印
doif [ -f $file ]; thenecho "$file是一個文件"let count++ fi
doneecho "/var/log文件夾下面一共有$count個文件"# 測試
[root@localhost shelldemo]# sh dome10.sh
192.168.10.101 is up
192.168.10.102 is down
192.168.10.103 is down
192.168.10.104 is down
192.168.10.105 is down
192.168.10.106 is up
192.168.10.1 is up
[root@localhost shelldemo]# vim dome10.sh
[root@localhost shelldemo]# vim dome11.sh
[root@localhost shelldemo]# chmod +x dome11.sh
[root@localhost shelldemo]# sh dome11.sh
dome11.sh:行3: 0: 未找到命令
/var/log/yum.log是一個文件
/var/log/Xorg.9.log是一個文件
/var/log/Xorg.0.log.old是一個文件
/var/log/Xorg.0.log是一個文件
/var/log/wtmp是一個文件
/var/log/wpa_supplicant.log是一個文件
/var/log/vmware-vmtoolsd-root.log是一個文件
/var/log/vmware-vmsvc-root.log是一個文件
/var/log/vmware-vgauthsvc.log.0是一個文件
/var/log/vmware-network.log是一個文件
/var/log/vmware-network.9.log是一個文件
/var/log/vmware-network.8.log是一個文件
/var/log/vmware-network.7.log是一個文件
/var/log/vmware-network.6.log是一個文件
/var/log/vmware-network.5.log是一個文件
/var/log/vmware-network.4.log是一個文件
/var/log/vmware-network.3.log是一個文件
/var/log/vmware-network.2.log是一個文件
/var/log/vmware-network.1.log是一個文件
/var/log/tallylog是一個文件
/var/log/spooler-20250827是一個文件
/var/log/spooler-20250817是一個文件
/var/log/spooler-20250810是一個文件
/var/log/spooler是一個文件
/var/log/secure-20250827是一個文件
/var/log/secure-20250817是一個文件
/var/log/secure-20250810是一個文件
/var/log/secure是一個文件
/var/log/mysqld.log是一個文件
/var/log/messages-20250827是一個文件
/var/log/messages-20250817是一個文件
/var/log/messages-20250810是一個文件
/var/log/messages是一個文件
/var/log/maillog-20250827是一個文件
/var/log/maillog-20250817是一個文件
/var/log/maillog-20250810是一個文件
/var/log/maillog是一個文件
/var/log/lastlog是一個文件
/var/log/grubby_prune_debug是一個文件
/var/log/firewalld是一個文件
/var/log/dmesg.old是一個文件
/var/log/dmesg是一個文件
/var/log/cron-20250827是一個文件
/var/log/cron-20250817是一個文件
/var/log/cron-20250810是一個文件
/var/log/cron是一個文件
/var/log/btmp是一個文件
/var/log/boot.log-20250830是一個文件
/var/log/boot.log-20250829是一個文件
/var/log/boot.log-20250827是一個文件
/var/log/boot.log-20250817是一個文件
/var/log/boot.log-20250816是一個文件
/var/log/boot.log-20250815是一個文件
/var/log/boot.log-20250814是一個文件
/var/log/boot.log是一個文件
/var/log文件夾下面一共有55個文件
示例:需要ping 通 某個網段 ?機器 ?并且 輸出 通和不通 反饋結果
# shell腳本
# 交互式寫一個網段
read -p "檢查網段:" ip
# ping一下
ping -c 3 -i 0.5 -W 1 $ip >/dev/null 2>&1
# 用if判斷
if [ $? -eq 0 ]; thenecho "$ip可以ping通">>ping.txt
elseecho "$ip不可以ping通">>ping.txt
fi# 測試
# 192.168.66.12不可能連接通
[root@localhost shelldemo]# sh dome12.sh
檢查網段:192.168.66.12
[root@localhost shelldemo]# cat ping.txt
192.168.10.106可以ping通
192.168.66.12不可以ping通
示例:九九乘法表
# 遍歷i從1到9
for i in $(seq 9);
do
# 遍歷j從1到ifor j in $(seq $i);doecho -n "$i*$j=$((i*j)) "doneecho -e "\n"
done# 測試
[root@localhost shelldemo]# sh dome13.sh
1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
示例:隨機生成一個15位的密碼
# shell腳本
# 隨機生成一個10位數的密碼
key="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
# 列出key的字符串數目
num=${#key}
# 遍歷
for i in $(seq 15); doindex=$[RANDOM%$num]password=$password${key:$index:1}
doneecho "密碼是$password"# 測試
[root@localhost shelldemo]# sh dome14.sh
密碼是aMcDjfRetHA2Wi1
[root@localhost shelldemo]# sh dome14.sh
密碼是sZdzcxaLMzUAnis
[root@localhost shelldemo]# sh dome14.sh
密碼是4zQTx9YS4kWkBSm
while循環
條件判斷型
適合「達到某個條件就停止」的場景。
bash
while [ 條件表達式 ]
do命令# 必須修改循環條件,否則死循環
done
示例:等待用戶輸入 yes/YES
# shell腳本
while [ "$y" != "yes" -a "$y" != "YES" ]do echo "請輸入yes/YES停止循環"read y
doneecho "循環已經停止"# 測試[root@localhost shelldemo]# sh dome15.sh
請輸入yes/YES停止循環
qwerty
請輸入yes/YES停止循環
fd
請輸入yes/YES停止循環
fghjk
請輸入yes/YES停止循環
hgfd
請輸入yes/YES停止循環
gfx
請輸入yes/YES停止循環
456789
請輸入yes/YES停止循環
resw
請輸入yes/YES停止循環
9ok,
請輸入yes/YES停止循環
fds
請輸入yes/YES停止循環
yes
循環已經停止
-
數值運算型
用 Bash 的算術表達式(( ))
或let
,實現類 C 的循環。
bash
# shell腳本
i=1
while(($i<3))
doecho $ilet i++ # 或者((i++))
done# 測試
[root@localhost shelldemo]# sh dome16.sh
1
2
-
無限循環(死循環)
需要內部用break
或exit
退出。
bash
while true
doread -p "請輸入字符串:" str[ "$str" == "quit" ] && exit 0
done
示例:死循環
# shell腳本
while true
doecho "請輸入字符串:"read yif [ "$y" == "yes" ]; thenexit 0 # 退出fi
done# 測試
[root@localhost shelldemo]# chmod dome17.sh
chmod: "dome17.sh" 后缺少操作數
Try 'chmod --help' for more information.
[root@localhost shelldemo]# chmod +x dome17.sh
[root@localhost shelldemo]# sh dome17.sh
請輸入字符串:
sdfg
請輸入字符串:
xcv
請輸入字符串:
oiug
請輸入字符串:
cv
請輸入字符串:
456
請輸入字符串:
poih
請輸入字符串:
xf
請輸入字符串:
yea^Hs^H^[[3~^H
請輸入字符串:
yes # 已退出
典型示例
-
計算 1…10 累加和
bash
count=0
num=1
while (( num <= 10 ))
docount=$(( count + num ))((num++))
done
echo "1-10 累加和:$count"
-
猜數字游戲(節選 while 片段)
num=$[RANDOM%100+1]
while true
doread -p "猜 1-100 的數:" caiif [ $cai -eq $num ]; thenecho "恭喜,猜對了!"exit 0elif [ $cai -gt $num ]; thenecho "猜大了"elseecho "猜小了"fi
done
示例:實時監控httpd的運行狀態
# shell腳本
while ps -aux|grep httpd|grep -v grep &>/dev/null
doecho "httpd正在運行"sleep 2
doneecho "httpd不在運行"# 測試
# 此時httpd開啟
[root@localhost shelldemo]# sh dome20.sh
httpd正在運行
httpd正在運行
httpd正在運行
httpd正在運行
httpd正在運行
httpd正在運行
httpd正在運行
httpd正在運行
...
# 此時關閉httpd
[root@localhost shelldemo]# sh dome20.sh
httpd不在運行
基本語法
case $變量 in模式1)命令1;;模式2)命令2;;*) # 通配符,相當于 default默認命令;;
esac # 反寫 case,表示結束
-
每個分支必須以右括號
)
結束。 -
每個分支命令塊以
;;
結束。 -
支持通配符:
*
匹配任意字符,?
匹配單個字符,|
表示“或”。
case循環
快速示例
bash
#!/bin/bash
case $1 in"hello")echo "Hello World!";;"test")echo "testing...";;"")echo "$0 沒有參數";;*) # 其余任何輸入echo "默認分支";;
esac
運行示例
$ ./demo.sh hello → Hello World!
$ ./demo.sh test → testing...
$ ./demo.sh → ./demo.sh 沒有參數
$ ./demo.sh abc → 默認分支
實用技巧
-
多模式匹配
bashcase $opt iny|Y|yes|YES) echo "確認" ;;n|N|no|NO) echo "取消" ;; esac
-
模式里可包含通配符
bashcase $filename in*.tar.gz) tar -zxf "$filename" ;;*.zip) unzip "$filename" ;; esac
-
與
bashread
搭配做簡單菜單read -p "選擇操作[start|stop|restart]: " action case $action instart) systemctl start nginx ;;stop) systemctl stop nginx ;;restart)systemctl restart nginx ;;*) echo "未知操作" ;; esac
示例:設置系統開機、關機和重啟
# shell腳本
case $1 in
"start")
systemctl start httpd.service
echo "服務已開啟"
;;"stop")
systemctl stop httpd.service
echo "服務已關閉"
;;"restart")
systemctl stop httpd.service
systemctl start httpd.service
echo "服務已重啟"
;;*)
echo "服務不存在,請輸入正確的服務 start stop restart"
;;
esac
測試結果:
[root@localhost shelldemo]# sh dome18.sh start
服務已開啟
[root@localhost shelldemo]# systemctl status httpd
● httpd.service - The Apache HTTP ServerLoaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)Active: active (running) since 六 2025-08-30 16:50:18 CST; 12s agoDocs: man:httpd(8)man:apachectl(8)Main PID: 10702 (httpd)Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"Tasks: 6CGroup: /system.slice/httpd.service├─10702 /usr/sbin/httpd -DFOREGROUND├─10706 /usr/sbin/httpd -DFOREGROUND├─10707 /usr/sbin/httpd -DFOREGROUND├─10708 /usr/sbin/httpd -DFOREGROUND├─10709 /usr/sbin/httpd -DFOREGROUND└─10710 /usr/sbin/httpd -DFOREGROUND8月 30 16:50:18 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
8月 30 16:50:18 localhost.localdomain httpd[10702]: AH00558: httpd: Could not reliably determine the server's fully qualifie...ssage
8月 30 16:50:18 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost shelldemo]# sh dome18.sh stop
服務已關閉
[root@localhost shelldemo]# systemctl status httpd.service
● httpd.service - The Apache HTTP ServerLoaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)Active: inactive (dead)Docs: man:httpd(8)man:apachectl(8)8月 30 16:50:18 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
8月 30 16:50:18 localhost.localdomain httpd[10702]: AH00558: httpd: Could not reliably determine the server's fully qualifie...ssage
8月 30 16:50:18 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
8月 30 16:50:38 localhost.localdomain systemd[1]: Stopping The Apache HTTP Server...
8月 30 16:50:39 localhost.localdomain systemd[1]: Stopped The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost shelldemo]# sh dome18.sh asdfghj
服務不存在,請輸入正確的服務 start stop restart
示例:用 case 編寫一個查看 ?cpu ? 內存 ?硬盤 資源使用情況
# shell腳本
# 提示查看用戶信息
echo "請查看用戶信息"
echo "1.CPU的使用情況"
echo "2.磁盤的使用情況"
echo "3.內存的使用情況"
echo "4.退出"
# 用戶交互
read -p "請輸入選項1、2、3、4:" de
# case語句
case $de in
"1")
top -bn1|grep Cpu
;;"2")
df -h
;;"3")
free -m
;;"4")
exit 0
;;*)
echo "請輸入正確的設備1、2、3、4"
;;esac# 運行
[root@localhost shelldemo]# sh dome22.sh
請查看用戶信息
1.CPU的使用情況
2.磁盤的使用情況
3.內存的使用情況
4.退出
請輸入選項1、2、3、4:1
%Cpu(s): 1.9 us, 20.8 sy, 0.0 ni, 77.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
[root@localhost shelldemo]# sh dome22.sh
請查看用戶信息
1.CPU的使用情況
2.磁盤的使用情況
3.內存的使用情況
4.退出
請輸入選項1、2、3、4:3total used free shared buff/cache available
Mem: 3770 1273 819 49 1677 2207
Swap: 3967 0 3967
[root@localhost shelldemo]# sh dome22.sh
請查看用戶信息
1.CPU的使用情況
2.磁盤的使用情況
3.內存的使用情況
4.退出
請輸入選項1、2、3、4:4
總結
通過上述腳本實踐,我們深刻體會到“簡單即是力量”的運維哲學:只需三十余行代碼,便能把晦澀的系統指標轉化為清晰易讀的管理視圖。用戶僅需輸入 1、2、3、4 即可在 CPU 負載、磁盤容量、內存占用與程序退出之間自由切換,無需再背冗長參數,也不必擔心誤操作帶來的風險。腳本在真實環境中已驗證可行,輸出格式與系統原生工具保持一致,方便直接粘貼到監控平臺或故障工單。未來可進一步擴展:加入循環菜單實現連續查詢、用顏色高亮關鍵閾值、將結果重定向到日志文件,甚至結合 cron 定時執行,實現無人值守巡檢。希望這段示例能為正在構建自動化運維體系的同行提供靈感,也期待社區共同迭代,讓 Shell 腳本在 DevOps 時代繼續煥發活力。