Shell 脚本编程核心语法:条件判断、循环与函数实战指南
目录一、判断服务是否运行的通用方法if 的前提二、if 条件语句三、Shell 函数四、case 条件语句五、while / until 循环六、for / select 循环七、select 循环菜单八、语句选用总结一句话记忆一、判断服务是否运行的通用方法if 的前提方法 命令看服务状态 systemctl status sshd / systemctl is-active sshd看进程 ps -C sshd看监听端口 ss -lntp | grep :22、lsof -i :22客户端测 ssh rootserver hostname、telnet server 22本地/远端扫端口 本地ss/netstat/lsof远端telnet/nmap/nc判断技巧先 grep 过滤特殊标记再 wc -l 转成行数比较结果是数字便于判断。二、if 条件语句语法三种分支# 单分支 if 条件表达式;then 指令 fi # 双分支 if 条件;then 指令1; else 指令2; fi # 多分支 if 条件1;then 指令1 elif 条件2;then 指令2 else 指令3 fi记忆点每个 if 对应一个 fi反写elif 要带 thenelse 不带/|| 可等价替代单/双分支。五种条件表达式写法if test 表达式;then ... fi if [ 表达式 ];then ... fi # 常用 if [[ 表达式 ]];then ... fi # 支持正则 ~ if ((算术表达式));then ... fi if 命令;then ... fi # 直接以命令返回值判断经典案例提炼思路判断数字/字符串[[ 123 ~1$ ]][ -z “$num” ]expr $a 1 看返回值内存监控free -m | awk ‘NR2{print $4}’小于 100 则发邮件crontab */3 * * * * 调度服务监控if ss -lnt|grep -q ‘:3306’ 判断 MySQL 是否在跑rsync 启停脚本按 $1 传参 start/stop/status/restart用 ss -lnt|grep -q ‘:873’ 判断状态三、Shell 函数三种写法function 函数名 () { ...; return n } # 标准 function 函数名 { ... } # 省略 () 函数名 () { ... } # 省略 function关键规则函数必须先定义后调用否则报 command not found调用不加 function 和括号函数名 或 函数名 参数1 参数2位置参数$1、2 、 2、2、#、∗ 、 *、∗、、$?都可当函数参数但 $0 仍是脚本名且父脚本参数会被临时掩盖return 退出函数并返回状态码exit 退出整个脚本局部变量用 local 定义离开函数即消失外部函数文件用 source / . 加载执行优先级别名 函数 命令 可执行文件递归示例function sum_out() { if [ $1 -eq 1 ];then sum1 else sum$[ $1 $(sum_out $[ $1 - 1 ]) ];fi echo $sum } sum_out 10 # 55⚠️ fork 炸弹 ){ : };:无限递归耗尽资源用 ulimit -u 100 限制进程数防御。四、case 条件语句语法case 变量 in 值1) 指令1 ;; 值2|值3) 指令2 ;; *) 默认指令 ;; esac适用场景变量值少且固定如 start/stop/restart、服务启动脚本 → 用 case取值判断、比较、范围判断 → 用 if应用面更广case 基本都可以用 if 替代企业案例控制 sshdcase $1 in start|stop|restart|reload|status) systemctl $1 sshd ;; *) usage;; esac用户管理脚本 user-mgrcase $action in -a|-d|-s) 增删查 /etc/users用 chattr i 防止被外部修改非 root 拒绝 [ $UID -ne 0 ] exit 1五、while / until 循环语法与区别while 条件; do 指令; done # 条件成立才循环 until 条件; do 指令; done # 条件不成立才循环与 while 相反while 常用于守护进程 / 无限循环配合 sleep 控制频率until 较少使用两者可互换until false ≡ 无限循环。数值运算((i))、((sumi))、((sum*i))、let sumsumi求和1~100 → ((sumi)); ((i))阶乘((sum*i))经典案例猴子吃桃lastday$[(today1)*2]while 迭代 9 次或用函数递归 $(sum $[$1-1])猜数字$[RANDOM%491] 随机数while true 循环[[ !g [ 0 − 9 ] g ~ ^[0-9]g[0−9]]] 校验纯数字猜对删临时文件 exit后台监控while true; do systemctl is-active sshd; sleep 5; done 守护进程监控网站每 3 秒 curl -o /dev/null -s --connect-timeout 5 $url手机短信平台菜单 bc 算余额money*10015 判断余额不足类 DDoS 封 IPwhile true 里 awk ‘{print $1}’ |sort|uniq -c 统计PV阈值且未封则 iptables -I INPUT -s $ip -j DROP按行读文件的 4 种方式exec /etc/hosts; while read line; do ...; done # exec 重定向 cat /etc/hosts | while read line; do ...; done # 管道 while read line; do ...; done /etc/hosts # done 处重定向推荐 IFS$\n; for line in $(cat file); do ...; done # 换行分隔后台运行 / 并发控制后台sh xx.sh 、nohup xx.sh 、screen控制bg/fg/jobs/kill %编号{ cmd;cmd; } 多命令后台wait 等待所有后台任务完成后再继续控制并发 ≤ CPU 数jobs$(jobs -l|wc -l)若 ≥ cpu 则 sleep 3 再检测否则 break六、for / select 循环for 两种语法# 列表型省略 in 列表 ≡ for i in $ for i in {1..5}; do ...; done for i in $(seq 5); do ...; done # C 语言型 for ((i1;i5;i)); do ...; done经典案例思路速记题目 核心写法求和/乘积 sum[ s u m i ] / ( ( s u m ∗ i ) ) 水仙花数拆位 n 1 [sumi] / ((sum*i)) 水仙花数 拆位 n1[sumi]/((sum∗i))水仙花数拆位n1[num/100] n2[ n u m [num%100/10] n3[num[num%10]立方和判断相等素数 双层循环i%j0 则 break九九乘法表 嵌套循环 echo -en n u m 2 ∗ num2*num2∗num1KaTeX parse error: Undefined control sequence: \t at position 6: [...]\̲t̲ 百钱买百鸡 …[countm*10**(j-1)]企业级案例批量改扩展名new$(echof i l e ∣ s e d ′ s / . t x t file|sed s/.txtfile∣sed′s/.txt/.jpg/); mv $file $new也可 rename批量启服务for s in crond atd chronyd; do systemctl enable $s; done批量重启主机for h in server{1…10}; do ssh root$h systemctl restart sshd; done扫描在线主机for i in( s e q 1254 ) ; d o p i n g − c 2172.25.254. (seq 1 254); do ping -c2 172.25.254.(seq1254);doping−c2172.25.254.i; done加 并发磁盘监控读 /tmp/hostsssh $host df -h使用率80% 发邮件MySQL 分库备份for db in web1 web2; do mysqldump -uroot $db $db.sql; done批量建用户while read username 随机密码( e c h o (echo (echou$RANDOM|md5sum|cut -c 3-11)chage -d 0 强制首登改密action 优雅显示 OK/FailLinux 生成随机数的 7 种方法$RANDOM0~32767可拼串后 md5 截取openssl rand -base64 8date %s%N纳秒head /dev/urandom|md5sumurandom 伪随机、random 真随机会阻塞cat /proc/sys/kernel/random/uuid、uuidgenmkpasswd -l 20 -d 4 -c 4 -C 4 -s 4长度/数字/小写/大写/特殊符号mktemp -u|sha1sum七、select 循环菜单语法PS3选择: # 自定义提示符 select 变量 in 列表 do ... # $REPLY 是用户输入的序号 done自动生成带序号的菜单等待用户输入用户输序号进入循环不会自动遍历靠用户选择推进除非 exit/break否则一直循环in 列表 可省略≡ in “$”经典一键安装 MySQL/httpd —— select 菜单 case $REPLY 函数封装 InstallService八、语句选用总结一句话记忆语句 典型场景条件表达式 [] [[]] (()) 简短判断文件存在、字符串空否if 取值判断、比较最常用for 有限次数常规循环while 守护进程、无限循环加 sleep 控制频率until while 的反向少用case 服务启动脚本、固定少量字符串select 菜单实际多用 cat here-doc 替代函数 逻辑模块化、减少重复代码0-9 ↩︎