Shell 脚本核心语法与企业实战案例
文章目录
- Shell 脚本核心语法与企业实战案例
- 一、if 条件语句
- 1. 基础语法
- 2. 企业实战案例
- (1)服务监控(Web / 数据库)
- (2)内存监控报警
- (3)服务启停脚本(以 rsync 为例)
- 二、Shell 函数
- 1. 语法格式
- 2. 实战示例(状态输出函数)
- 三、while 与 until 循环
- 1. 核心应用场景
- 2. 按行读文件的 4 种方式
- 3. 企业案例
- (1)防 DDoS 攻击(封高频 IP)
- (2)网站监控(每隔 3 秒检测)
- 四、for循环
- 1. for 循环实战案例
- (1)批量操作
- 2. 生成随机数的 7 种方法
- 五、语句使用场景总结
Shell 脚本核心语法与企业实战案例
一、if 条件语句
1. 基础语法
-
单分支结构
(两种等价写法):
# 写法1 if <条件表达式>then 指令 fi# 写法2(推荐) if <条件表达式>;then指令 fi
-
条件表达式:可使用
test
、[]
、[[]]
、(())
或直接用命令。 -
嵌套使用
:注意
if
与
fi
成对匹配,建议缩进对齐:
if <条件1>;thenif <条件2>;then指令fi fi
-
与逻辑运算等价转换
:
[ ! -d /tmp/laoma ] && mkdir /tmp/laoma
等价于:
if [ ! -d /tmp/laoma ];thenmkdir /tmp/laoma fi
2. 企业实战案例
(1)服务监控(Web / 数据库)
-
监控方法
:
- 端口监控:本地用
netstat
/ss
/lsof
,远端用telnet
/nmap
/nc
。 - 进程监控:
ps -ef | grep 服务名 | wc -l
(统计进程数)。 - 客户端模拟:
wget
/curl
检测 Web,mysql -u用户 -p密码 -e "语句"
检测数据库。
- 端口监控:本地用
(2)内存监控报警
每 3 分钟检查内存,低于 100M 发邮件:
#!/bin/bash
FreeMem=$(free -m | awk 'NR==2 {print $4}')
if [ $FreeMem -lt 100 ];thenecho "Mem is lower than 100M" | mail -s "FreeMem: ${FreeMem}M" root@localhost
fi
# 加入定时任务:*/3 * * * * /path/monitor_mem.sh
(3)服务启停脚本(以 rsync 为例)
#!/bin/bash
if [ $# -ne 1 ];thenecho "Usage: $0 [ start | stop | restart | status ]"exit 1
fiif [ "$1" = "start" ];thenrsync --daemonsleep 2if ss -lnt|grep -q ':873';thenecho "rsyncd is started."fi
elif [ "$1" = "stop" ];thenpkill rsync &>/dev/nullsleep 2if ! ss -lnt|grep -q ':873';thenecho "rsyncd is stopped."fi
# 省略restart/status逻辑
fi
二、Shell 函数
1. 语法格式
-
标准写法
function 函数名 () {指令...return n # 返回值(可选) }
2. 实战示例(状态输出函数)
function print () {if [ "$1" == "PASS" ];thenecho -e '\033[1;32mPASS\033[0;39m' # 绿色elif [ "$1" == "FAIL" ];thenecho -e '\033[1;31mFAIL\033[0;39m' # 红色elif [ "$1" == "DONE" ];thenecho -e '\033[1;35mDONE\033[0;39m' # 紫色fi
}
三、while 与 until 循环
1. 核心应用场景
while
:适合守护进程(持续执行)、按行读文件等,需配合sleep
控制频率。until
:条件为false
时持续执行(与while true
类似)。
2. 按行读文件的 4 种方式
以读取/etc/hosts
为例:
# 方式1:exec重定向
exec < /etc/hosts
while read line;do echo $line;done# 方式2:管道传递
cat /etc/hosts | while read line;do echo $line;done# 方式3:done后重定向
while read line;do echo $line;done < /etc/hosts# 方式4:修改分隔符(for循环)
IFS=$'\n';for line in $(cat /etc/hosts);do echo $line;done
3. 企业案例
(1)防 DDoS 攻击(封高频 IP)
#!/bin/bash
logfile=$1
while true;do# 统计IP访问次数awk '{print $1}' $logfile | grep -v "^$" | sort | uniq -c > /tmp/tmp.logwhile read line;doip=$(echo $line | awk '{print $2}')count=$(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 DROPecho "$ip is dropped" >> /tmp/droplist_$(date +%F).logfidone < /tmp/tmp.logsleep 3600 # 每小时执行一次
done
(2)网站监控(每隔 3 秒检测)
#!/bin/bash
if [ $# -ne 1 ];thenecho "Usage: $0 url"exit 1
fi
url="$1"
while true;doif curl -o /dev/null -s --connect-timeout 5 $url;thenecho "$url is ok."elseecho "$url is error."fisleep 3
done
四、for循环
1. for 循环实战案例
(1)批量操作
-
批量修改文件扩展名(txt→jpg):
for file in $(ls *.txt);domv $file $(echo $file|sed 's/.txt$/.jpg/') done
-
批量启动服务:
for service in crond atd chronyd;dosystemctl enable $service done
-
批量备份 MySQL 数据库:
# 备份web1、web2库 for db in web1 web2;domysqldump -uroot $db > ${db}.sql done
九九乘法表
#!/bin/bash for num1 in {1..9} dofor ((num2=1;num2<=num1;num2++))doecho -en "$num2*$num1=$[ num2 * num1 ]\t"doneecho done
(2)网络监控(检测在线主机)
#!/bin/sh
for i in $(seq 1 254);doIP=172.25.254.$iping -c2 $IP &> /dev/nullif [ $? -eq 0 ];thenecho "$IP is online" >> node_online.txtelseecho "$IP is offline" >> node_offline.txtfi
done
2. 生成随机数的 7 种方法
# 方法1:RANDOM(0-32767)+ md5
echo "laoma$RANDOM"|md5sum|cut -c 1-8# 方法2:openssl
openssl rand -base64 8# 方法3:date纳秒
date +%s%N# 方法4:/dev/urandom + md5
head /dev/urandom | md5sum# 方法5:UUID
cat /proc/sys/kernel/random/uuid; uuidgen# 方法6:mkpasswd(指定长度和字符)
mkpasswd -l 20 -d 4 -c 4 -C 4 -s 4# 方法7:mktemp + sha1
mktemp -u | sha1sum
五、语句使用场景总结
if
:少量条件判断(最常用)。for
:批量循环处理(文件、服务、主机等)。while
:守护进程、无限循环(需sleep
控制)。case
:服务启动脚本(固定参数匹配)。- 函数:简化重复逻辑,提升代码可读性。