一、Shell脚本基础概念
Shell脚本(Shell Script)是通过文本文件编写的命令集合,由Shell命令解释器逐行解析执行。作为Unix/Linux系统的核心自动化工具,它能完成:
系统管理任务自动化
复杂命令序列的封装
文件批量处理
服务状态监控等
典型应用场景:
#!/bin/bash
# 自动备份网站目录并删除7天前的备份
tar -czf /backup/web_$(date +%Y%m%d).tar.gz /var/www/html
find /backup -name "web_*.tar.gz" -mtime +7 -exec rm {} \;
二、Shell命令解释器
常见Shell类型
Bash (Bourne-Again Shell):Linux默认Shell
Zsh:功能增强型Shell
Ksh (Korn Shell):Unix传统Shell
Shebang声明
#!/usr/bin/env bash # 推荐写法,自动查找bash路径
#!/bin/bash # 传统写法
三、变量操作
1. 变量基础
name="John" # 定义变量
echo $name # 输出变量
echo ${name} # 推荐写法,明确变量边界
2. 环境变量
export PATH=$PATH:/custom/bin # 设置环境变量
env | grep LANG # 查看环境变量
3. 特殊变量
$0 脚本名称
$1 第一个参数
$# 参数个数
$@ 所有参数列表
$? 上条命令退出状态
4.Shell数值运算方法对比表
运算方式 | 语法示例 | 特点说明 | 适用场景 |
---|---|---|---|
$(( )) |
echo $((a + b)) |
1. 支持整数运算 2. 无需转义符号 |
常规算术运算 |
let |
let "result=a*b" |
1. 支持复合运算 2. 直接修改变量 |
需要保存运算结果 |
expr |
expr $a \* $b |
1. 兼容性最好 2. 需要转义特殊符号 |
老旧系统环境 |
bc |
echo "scale=2;3/7" | bc |
1. 支持浮点运算 2. 可设定精度 |
精确计算需求 |
四、流程控制
1.状态检测
检测项 | 运算符 | 示例 | 说明 |
---|---|---|---|
空字符串 | -z |
[ -z "$var" ] |
变量值为空或未定义时返回真 |
非空字符串 | -n |
[[ -n $str ]] |
变量有非空值时返回真 |
存在性检查 | = |
[ "$var" = "exists" ] |
需要显式值对比 |
2. 条件判断
if [ -f "/path/file" ]; then
echo "文件存在"
elif [ -d "/path" ]; then
echo "目录存在"
else
echo "路径无效"
fi
# 使用双括号支持高级比较
if (( $# > 2 )); then
echo "参数过多"
fi
3. 多条件判断
case $OS in
"Linux")
echo "使用apt/yum"
;;
"Darwin")
echo "使用brew"
;;
*)
echo "未知系统"
esac
4.数值比较运算符表
运算符 | 数学符号 | 描述 | 示例 | 兼容性 |
---|---|---|---|---|
-eq |
= | 等于 | [ "$a" -eq 5 ] |
所有Shell |
-ne |
≠ | 不等于 | [[ "$a" -ne 10 ]] |
所有Shell |
-gt |
> | 大于 | (( a > b )) |
Bash/Zsh |
-ge |
≥ | 大于等于 | [ $a -ge $b ] |
所有Shell |
-lt |
< | 小于 | [[ $a -lt 20 ]] |
所有Shell |
-le |
≤ | 小于等于 | (( a <= b )) |
Bash/Zsh |
5.字符串操作对照表
运算符 | 功能描述 | 标准写法 | 增强写法(双方括号) |
---|---|---|---|
= |
字符串相等 | [ "$s1" = "$s2" ] |
[[ $s1 == $s2 ]] |
!= |
字符串不等 | [ "$s1" != "text" ] |
[[ $s1 != pattern* ]] |
> |
按ASCII码顺序大于 | 不支持 | [[ "apple" > "banana" ]] |
< |
按ASCII码顺序小于 | 不支持 | [[ "cat" < "dog" ]] |
五、循环结构
1. For循环
for i in {1..5}; do
echo "第$i次循环"
done
# 遍历文件
for file in *.log; do
gzip "$file"
done
2. While循环
counter=0
while [ $counter -lt 5 ]; do
echo $counter
((counter++))
done
# 读取文件内容
while IFS= read -r line; do
echo "处理: $line"
done < data.txt
六、函数编程
function calc_sum {
local sum=$(( $1 + $2 )) # 局部变量
return $sum
}
calc_sum 10 20
echo "计算结果: $?"
七、脚本间调用
1. 调用方式
# 子进程执行
./subscript.sh param1 param2
# 当前进程执行
source config.sh
2. 参数传递示例
main.sh:
#!/bin/bash
echo "主脚本启动"
./sub.sh "参数1" "参数2"
八、C语言集成调用
#include <stdlib.h>
int main() {
//execl("./test.sh","b.sh",(char*)0)
int ret = system("./backup.sh");
if (WIFEXITED(ret)) {
printf("退出码: %d\n", WEXITSTATUS(ret));
}
return 0;
}
编译执行:
gcc -o caller caller.c
./caller
九、文本处理三剑客
1. Sed流编辑器
# 替换文本内容
sed 's/old/new/g' input.txt > output.txt
# 删除空行
sed '/^$/d' file.txt
2. Awk数据处理器
# 统计文件行数
awk 'END{print NR}' data.log
# 字段处理
awk -F',' '{print $1, $3}' users.csv
3. 正则表达式实战
# 匹配IP地址
grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log
# 提取邮箱地址
awk '/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/ {print $0}' contacts.txt
十、高级技巧扩展
调试技巧
set -x # 开启调试模式
set +x # 关闭调试
错误处理
set -euo pipefail # 严格模式
trap "echo 发生错误" ERR
性能优化
# 避免频繁启动子进程
while read line; do
process "$line"
done < <(grep pattern bigfile.txt)
浮点运算方法对比
方法 | 示例 | 精度控制 | 输出示例 |
---|---|---|---|
bc |
echo "3.14+2.718" | bc |
scale=N设置小数位 | 5.858 |
awk |
awk 'BEGIN{print 1/3}' |
PREC变量控制 | 0.333333 |
printf |
printf "%.2f" 3.1415 |
格式字符串指定 | 3.14 |
dc |
echo "4k 3 7 / p" | dc |
k命令设置精度 | 0.4285 |
十一、最佳实践建议
脚本头部添加版本和说明注释
重要操作添加确认提示
使用
$(cmd)
代替反引号处理含空格路径时用双引号包裹变量
设置合理的执行权限(755/700)
常见错误对照表
错误示例 正确写法 问题分析 [ $var = text ]
[ "$var" = "text" ]
变量未引号导致空格解析错误 [[ 100 > 20 ]]
[[ "100" -gt 20 ]]
字符串与数值比较类型混淆 echo $num1+$num2
echo $((num1+num2))
未使用算术展开导致字符串拼接 if [ ! -z $var ]; then
if [[ -n "$var" ]]; then
双重否定导致逻辑不清晰
十二、服务器健康监控与自动化维护系统
1. 智能监控告警
check_cpu_usage() {
local threshold=85
local usage=$(top -bn1 | awk '/Cpu/{print 100-$8}')
# 动态调整阈值
[ $usage -gt 90 ] && threshold=95
if (( $(echo "$usage > $threshold" | bc) )); then
send_alert "CPU过载警告" "当前使用率: ${usage}%"
fi
}
2. 日志分析引擎
analyze_ssh_logins() {
awk '
/Accepted publickey/ {
users[$9]++
ips[$11]++
}
END {
print "成功登录统计:"
print "用户\t次数"
for(u in users) print u "\t" users[u]
print "\nIP统计:"
for(ip in ips) print ip "\t" ips[ip]
}' /var/log/auth.log
}
3. 自动维护机器人
clean_old_files() {
# 安全删除7天前临时文件
find /tmp -type f -name "*.tmp" \
-mtime +7 \
-exec sh -c 'echo "删除: {}"; rm {}' \;
}
4.主程序
#!/bin/bash
# 主调度程序
# 加载模块
source modules/system_monitor.sh
source modules/log_analyzer.sh
source modules/auto_cleaner.sh
source modules/backup_manager.sh
# 初始化环境
mkdir -p logs reports backups
while true; do
check_cpu
check_memory
check_disk
analyze_errors "/var/log/nginx/error.log"
clean_tmp_files
if [ $(date +%H) -eq 2 ]; then # 每天凌晨2点执行
backup_database
fi
sleep 300 # 5分钟轮询
done