以下是 Shell 脚本编写的详细指南,涵盖基础语法、常用操作和实战案例,帮助你快速入门并高效使用!
Shell 脚本编写的详细指南
1. Shell 脚本基础
1.1 脚本文件结构
#!/bin/bash # Shebang 行(指定解释器,如 Bash)
# 注释:用 # 开头的行
VERSION="1.0" # 变量声明
echo "Hello, World!" # 执行命令
1.2 执行脚本
chmod +x script.sh # 赋予执行权限
./script.sh # 当前目录执行
bash script.sh # 显式指定解释器执行
2. 变量与运算符
2.1 变量类型
• 普通变量:name="Alice"
• 数组变量:fruits=("apple" "banana" "cherry")
• 特殊变量:$0
(脚本名)、$1
(第一个参数)、$#
(参数个数)
2.2 运算符
# 算术运算
result=$((5 + 3 * 2)) # 结果为 11
# 字符串拼接
greeting="Hello, $name!"
# 比较运算(等于、不等于、大于等)
if [ $age -gt 18 ]; then
echo "Adult"
fi
# 逻辑运算
if [ $score -ge 90 ] && [ $attendance -eq 100 ]; then
echo "A+ Grade"
fi
3. 流程控制
3.1 条件分支(if/elif/else)
if [ $num -eq 0 ]; then
echo "Zero"
elif [ $num -lt 0 ]; then
echo "Negative"
else
echo "Positive"
fi
3.2 循环结构
# for 循环(遍历列表)
for fruit in "apple" "banana" "orange"; do
echo "Fruit: $fruit"
done
# while 循环(条件判断)
count=0
while [ $count -lt 5 ]; do
echo "Count: $count"
((count++))
done
# until 循环(直到条件满足)
count=5
until [ $count -le 0 ]; do
echo "Count: $count"
((count--))
done
4. 命令与工具
4.1 文本处理
• cut
:提取字段
echo "name: Alice, age: 30" | cut -d':' -f2 # 输出 " Alice"
• awk
:文本分析
awk '{print $1}' file.txt # 提取每行第一个字段
• sed
:流编辑器
sed 's/foo/bar/g' file.txt # 将文件中所有 foo 替换为 bar
4.2 文件操作
# 判断文件是否存在
if [ -f "$filename" ]; then
echo "File exists"
fi
# 递归删除目录
rm -rf /path/to/directory
# 压缩/解压
tar -czvf backup.tar.gz /data # 压缩
tar -xzvf backup.tar.gz # 解压
5. 函数与参数
5.1 定义函数
function greet() {
local name="$1" # 第一个参数
echo "Hello, $name!"
}
greet "Alice" # 调用函数
5.2 参数传递
sum() {
local a="$1"
local b="$2"
echo $((a + b))
}
result=$(sum 5 3)
echo "Sum: $result" # 输出 8
6. 调试与错误处理
6.1 调试技巧
• 启用调试模式:在脚本前加 -x
bash -x script.sh # 显示每条执行的命令
• 打印变量值:echo "Variable: $var"
6.2 错误处理
if ! command; then
echo "Command failed" >&2
exit 1
fi
# 使用 trap 捕获信号
trap 'echo "Script interrupted"' SIGINT
7. 实战案例
7.1 文件备份
#!/bin/bash
BACKUP_DIR="/backup"
SOURCE_DIR="/data"
FILENAME="backup_$(date +%Y%m%d_%H%M%S).tar.gz"
tar -czvf "$BACKUP_DIR/$FILENAME" "$SOURCE_DIR"
echo "Backup completed: $FILENAME"
7.2 日志分析
#!/bin/bash
LOG_FILE="/var/log/app.log"
ERROR_COUNT=$(grep "ERROR" "$LOG_FILE" | wc -l)
if [ $ERROR_COUNT -gt 0 ]; then
echo "Errors found: $ERROR_COUNT"
mail -s "Log Alert" admin@example.com < "$LOG_FILE"
fi
7.3 监控磁盘空间
#!/bin/bash
DISK_PATH="/dev/sda1"
USAGE=$(df -h "$DISK_PATH" | awk '{print $5}')
if [ "$USAGE" -ge "90%" ]; then
echo "Disk usage is over 90%: $USAGE"
ssh user@remote_server "sudo /path/to/cleanup_script.sh"
fi
8. 高级技巧
8.1 正则表达式
# 匹配邮箱地址
if [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "Valid email"
fi
8.2 并行处理
# 使用 xargs 并行下载
wget -r -l1 http://example.com/files/ | grep "html$" | xargs -n 5 wget
8.3 脚本优化
# 使用本地变量加速
local var="$1" # 减少全局变量查找
9. 常见问题
- 权限问题:确保脚本有执行权限(
chmod +x
)。 - 路径问题:使用绝对路径或
source
调用脚本。 - 空值处理:对变量进行空值检查(
[ -z "$var" ]
)。 - 跨平台兼容性:尽量使用 POSIX-compliant 语法。
附录:Shell 脚本开发工具
• VS Code + Shell Explorer:语法高亮和调试支持。
• Git 版本控制:管理脚本变更历史。
• Makefile:复杂任务的分步执行。