在 Linux 日常运维和开发中,Shell 脚本的价值在于将重复、繁琐的任务自动化。下面是一些最常遇到的场景及其典型写法,你可以直接修改使用。
1. 日志分析与信息提取
假设你有一个 Web 服务器访问日志 access.log,每行格式为“IP 时间 请求 状态码 大小”。统计访问量最高的前 5 个 IP:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -5
如果想实时监控日志中某个关键字(如 ERROR)的出现:
tail -f /var/log/syslog | grep --line-buffered "ERROR"
当需要按时间段过滤日志,例如提取 10:00 到 11:00 之间的记录,可借助 awk 比较时间字段:
awk '$2 >= "10:00:00" && $2 <= "11:00:00"' access.log
2. 批量文件处理
将当前目录下所有 .jpg 文件重命名为 .jpeg:
for file in *.jpg; do mv "$file" "${file%.jpg}.jpeg"; done
如果文件名包含空格,务必使用双引号保护变量。更安全的做法是用 find,例如将所有 *.txt 文件转换为大写:
find . -name "*.txt" -exec sh -c 'mv "$0" "$(echo "$0" | tr "[:lower:]" "[:upper:]")"' {} \;
批量修改文件内容,比如把所有 .conf 文件中的 port=80 改成 port=8080:
sed -i 's/port=80/port=8080/g' *.conf
3. 系统监控与告警
监控磁盘使用率,当任一分区超过 80% 时发送邮件(需配置邮件服务):
df -h | awk 'NR>1 {gsub(/%/,"",$5); if($5+0 > 80) print $1, $5"%"}' | \
while read output; do
echo "磁盘空间告警: $output" | mail -s "磁盘告警" admin@example.com
done
监控 CPU 负载,超过阈值时记录到日志:
load=$(uptime | awk -F 'load average:' '{print $2}' | cut -d, -f1 | xargs)
if (( ${load%.*} > 4 )); then
echo "$(date): 高负载 ${load}" >> /var/log/load_warning.log
fi
可将脚本加入 crontab 每 5 分钟执行一次:
*/5 * * * * /path/to/monitor_script.sh
4. 备份与同步
用 rsync 增量备份网站目录到远程服务器:
rsync -avz --delete /var/www/html/ user@backup-server:/backups/html/
本地压缩备份并保留最近 7 天的副本:
tar -czf "/backups/myapp_$(date +%Y%m%d).tar.gz" /opt/myapp
find /backups -name "myapp_*.tar.gz" -mtime +7 -delete
5. 自动化部署与初始化
一套简单的应用更新流程(拉取代码,重启服务):
cd /opt/myapp || exit 1
git pull origin main
systemctl restart myapp.service
在新建服务器上批量安装软件包:
for pkg in nginx certbot python3-pip; do
apt-get install -y "$pkg"
done
6. 用户与权限管理
批量创建用户并设置默认密码(请在实际使用中改为更安全的方式):
while read user; do
useradd -m "$user"
echo "${user}:default123" | chpasswd
done < userlist.txt
扫描 /home 下权限过于开放(777)的文件:
find /home -type f -perm 0777 -exec ls -l {} \;
7. 实用小片段
- 随机生成 16 位密码:
tr -dc A-Za-z0-9 </dev/urandom | head -c 16; echo - 查看所有监听端口:
ss -tlnp - 快速统计代码行数:
find . -name "*.py" -exec cat {} \; | wc -l
要点:书写脚本时,始终在文件开头声明解释器和基本选项以提高健壮性:
#!/bin/bash
set -euo pipefail
set -e 让脚本在命令失败时立即退出,set -u 阻止使用未定义变量,set -o pipefail 让管道中任一命令失败都能被捕获。这些小习惯能避免很多意外。
以上场景覆盖了日常工作的主要需求。当你面对一个新任务时,先别急着写大程序,试着用简单命令链或循环完成,就能解决大部分问题。