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类型
Bash (Bourne-Again Shell):Linux默认Shell
Zsh:功能增强型Shell
Ksh (Korn Shell):Unix传统Shell
Shebang声明
#!/usr/bin/env bash # 推荐写法,自动查找bash路径
#!/bin/bash # 传统写法
name="John" # 定义变量
echo $name # 输出变量
echo ${name} # 推荐写法,明确变量边界
export PATH=$PATH:/custom/bin # 设置环境变量
env | grep LANG # 查看环境变量
$0 脚本名称
$1 第一个参数
$# 参数个数
$@ 所有参数列表
$? 上条命令退出状态
运算方式 | 语法示例 | 特点说明 | 适用场景 |
---|---|---|---|
$(( )) |
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. 可设定精度 |
精确计算需求 |
检测项 | 运算符 | 示例 | 说明 |
---|---|---|---|
空字符串 | -z |
[ -z "$var" ] |
变量值为空或未定义时返回真 |
非空字符串 | -n |
[[ -n $str ]] |
变量有非空值时返回真 |
存在性检查 | = |
[ "$var" = "exists" ] |
需要显式值对比 |
if [ -f "/path/file" ]; then
echo "文件存在"
elif [ -d "/path" ]; then
echo "目录存在"
else
echo "路径无效"
fi
# 使用双括号支持高级比较
if (( $# > 2 )); then
echo "参数过多"
fi
case $OS in
"Linux")
echo "使用apt/yum"
;;
"Darwin")
echo "使用brew"
;;
*)
echo "未知系统"
esac
运算符 | 数学符号 | 描述 | 示例 | 兼容性 |
---|---|---|---|---|
-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 |
运算符 | 功能描述 | 标准写法 | 增强写法(双方括号) |
---|---|---|---|
= |
字符串相等 | [ "$s1" = "$s2" ] |
[[ $s1 == $s2 ]] |
!= |
字符串不等 | [ "$s1" != "text" ] |
[[ $s1 != pattern* ]] |
> |
按ASCII码顺序大于 | 不支持 | [[ "apple" > "banana" ]] |
< |
按ASCII码顺序小于 | 不支持 | [[ "cat" < "dog" ]] |
for i in {1..5}; do
echo "第$i次循环"
done
# 遍历文件
for file in *.log; do
gzip "$file"
done
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 "计算结果: $?"
# 子进程执行
./subscript.sh param1 param2
# 当前进程执行
source config.sh
main.sh:
#!/bin/bash
echo "主脚本启动"
./sub.sh "参数1" "参数2"
#include
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
# 替换文本内容
sed 's/old/new/g' input.txt > output.txt
# 删除空行
sed '/^$/d' file.txt
# 统计文件行数
awk 'END{print NR}' data.log
# 字段处理
awk -F',' '{print $1, $3}' users.csv
# 匹配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)
代替反引号错误示例 | 正确写法 | 问题分析 |
---|---|---|
[ $var = text ] |
[ "$var" = "text" ] |
变量未引号导致空格解析错误 |
[[ 100 > 20 ]] |
[[ "100" -gt 20 ]] |
字符串与数值比较类型混淆 |
echo $num1+$num2 |
echo $((num1+num2)) |
未使用算术展开导致字符串拼接 |
if [ ! -z $var ]; then |
if [[ -n "$var" ]]; then |
双重否定导致逻辑不清晰 |
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
}
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
}
clean_old_files() {
# 安全删除7天前临时文件
find /tmp -type f -name "*.tmp" \
-mtime +7 \
-exec sh -c 'echo "删除: {}"; rm {}' \;
}
#!/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
Bash参考手册https://www.gnu.org/software/bash/manual/
Awesome Shellhttps://github.com/alebcay/awesome-shell
ShellCheck在线校验https://www.shellcheck.net/