10分钟上手Shell编程,搞定Linux自动化
大家好,今天和大家深入聊聊 Shell 编程——这个 Linux/Unix 系统下的“瑞士军刀”。无论是自动化运维、批量处理文件,还是编写简单工具脚本,Shell 都能以简洁的语法完成复杂任务。本文从基础语法到实战案例,带大家快速掌握 Shell 编程的核心能力。
一、Shell 编程基础:3 个核心知识点
1. 脚本开头与执行方式
• 指定解释器:脚本首行必须声明解释器,#!/bin/bash 是最常用的 Bash 解释器(兼容绝大多数 Linux 系统)。
• 执行权限:新建脚本后需添加执行权限:chmod +x script.sh。
• 运行方式:
◦ 直接运行:./script.sh(需在脚本所在目录)。
◦ 指定解释器运行:bash script.sh(无需执行权限)。

2. 变量与参数传递
• 变量定义:变量名=值(等号两侧无空格),如 name="Shell"。
• 变量使用:$变量名 或 ${变量名},如 echo $name。
• 位置参数:脚本后紧跟的参数,$1 表示第一个参数,$2 第二个,$* 所有参数。
#!/bin/bash
# 接收用户输入的两个参数,计算和
a=$1
b=$2
sum=$((a + b)) # 整数运算
echo "参数 $a + $b = $sum"
运行:./calc.sh 10 20,输出:参数 10 + 20 = 30。
3. 条件判断:关系运算符与逻辑判断
Shell 中条件判断需用 [ 表达式 ](括号两侧必须有空格),结合关系运算符实现逻辑判断,常用运算符如下:
运算符 说明 示例(a=10, b=20)
-eq 两数相等 [ $a -eq $b ]
-ne 两数不相等 [ $a -ne $b ]
-gt 左数大于右数 [ $a -gt $b ]
-lt 左数小于右数 [ $a -lt $b ]
-f 判断文件是否存在且为普通文件 [ -f test.txt ]
#!/bin/bash
# 判断文件是否存在,不存在则创建
file="test.txt"
if [ -f $file ]; then
echo "$file 已存在"
else
touch $file
echo "$file 创建成功"
fi
二、实战案例 1:批量备份日志文件
日常运维中,需定期备份日志并按日期命名,用 Shell 脚本可实现自动化:
#!/bin/bash
# 日志备份脚本:备份 /var/log 下的日志到 /backup/logs
backup_dir="/backup/logs"
log_dir="/var/log"
date=$(date +%Y%m%d) # 获取当前日期,格式:20240520
# 创建备份目录(不存在则创建)
if [ ! -d $backup_dir ]; then
mkdir -p $backup_dir
fi
# 压缩日志文件并备份
tar -zcvf $backup_dir/log_backup_$date.tar.gz $log_dir/*.log
# 判断备份是否成功
if [ $? -eq 0 ]; then # $? 是上一条命令的执行结果,0 表示成功
echo "日志备份成功,文件:$backup_dir/log_backup_$date.tar.gz"
else
echo "日志备份失败"
fi
核心技巧:
• mkdir -p:递归创建目录,避免多级目录不存在的报错。
• date +%Y%m%d:自定义日期格式,用于文件名区分版本。
• $?:获取上一条命令的退出状态,0 为成功,非 0 为失败。
三、实战案例 2:服务器磁盘空间监控告警
当服务器磁盘使用率超过阈值时,自动发送告警信息(这里用 echo 模拟,实际可替换为邮件/短信接口):
#!/bin/bash
# 磁盘空间监控:使用率超过 80% 则告警
threshold=80 # 阈值 80%
# 遍历所有挂载点,获取使用率(排除 tmpfs 等虚拟文件系统)
df -h | grep -vE 'tmpfs|loop|udev' | awk '{print $5, $6}' | while read usage mount; do
# 提取数字(去掉 % 号)
usage_num=${usage%%}
# 比较使用率与阈值
if [ $usage_num -gt $threshold ]; then
echo "⚠️ 告警:$mount 磁盘使用率已达 $usage,超过阈值 $threshold%"
fi
done
核心技巧:
• df -h:查看磁盘空间,-h 以人类可读格式显示。
• grep -vE:排除不需要的行(虚拟文件系统)。
• awk '{print $5, $6}':提取第 5 列(使用率)和第 6 列(挂载点)。
• ${usage%%}:截取字符串,去掉末尾的 % 号,获取纯数字。
四、实战案例 3:批量修改文件名
将目录下所有 .txt 文件批量改为 .log 格式,高效处理文件重命名需求:
#!/bin/bash
# 批量修改文件名:将当前目录下的 .txt 改为 .log
for file in $(ls *.txt); do
# 提取文件名(去掉 .txt 后缀)
filename=${file%.txt}
# 重命名
mv $file ${filename}.log
done
echo "批量重命名完成!"
核心技巧:
• for file in $(ls *.txt):循环遍历所有 .txt 文件。
• ${file%.txt}:字符串截取,去掉文件后缀 .txt,保留文件名主体。
五、Shell 编程避坑指南
1. 空格问题:条件判断 [ ] 两侧、运算符前后必须有空格,如 [ $a -gt $b ] 不能写成 [$a -gt $b]。
2. 变量引用:涉及字符串拼接或特殊字符时,用 ${变量名} 而非 $变量名,避免歧义。
3. 路径处理:尽量使用绝对路径,避免脚本在不同目录执行时因相对路径报错。
4. 权限问题:脚本执行前需确保有执行权限(chmod +x),操作系统文件需用 sudo 运行。
Shell 编程的核心是“简洁高效”,无需复杂语法,就能完成大量自动化任务。以上案例覆盖了日常开发和运维中的高频场景,掌握这些技巧后,你可以根据实际需求扩展更多脚本。











