Shell脚本进阶技巧
Shell脚本进阶技巧
数组操作
定义和使用
# 定义数组
arr=("apple" "banana" "cherry")
# 访问元素
echo ${arr[0]} # 第一个元素
echo ${arr[@]} # 所有元素
echo ${#arr[@]} # 数组长度
# 添加元素
arr+=("date")
# 遍历数组
for item in "${arr[@]}"; do
echo $item
done
# 删除元素
unset arr[1]
字符串处理
内置操作
str="Hello World"
# 长度
echo ${#str}
# 子串
echo ${str:0:5} # Hello
echo ${str:6} # World
# 替换
echo ${str/World/Linux} # Hello Linux
# 删除匹配
filename="archive.tar.gz"
echo ${filename%.gz} # archive.tar
echo ${filename%%.*} # archive
echo ${filename#*.} # tar.gz
echo ${filename##*.} # gz
参数扩展
# 默认值
echo ${var:-default} # var为空时返回default
echo ${var:=default} # var为空时赋值default
echo ${var:+value} # var非空时返回value
echo ${var:?error} # var为空时报错退出
# 验证
file="test.txt"
echo ${file:?"文件名不能为空"}
进程替换
# 比较两个命令的输出
diff <(ls dir1) <(ls dir2)
# 同时读取多个文件
while read -r line1 <&3 && read -r line2 <&4; do
echo "$line1 - $line2"
done 3< file1.txt 4< file2.txt
陷阱处理
#!/bin/bash
# 定义清理函数
cleanup() {
echo "执行清理..."
rm -f /tmp/lockfile
rm -f /tmp/data.txt
}
# 设置陷阱
trap cleanup EXIT
trap 'exit 1' INT TERM
# 创建锁文件
touch /tmp/lockfile
echo "脚本运行中..."
sleep 10
echo "脚本完成"
# EXIT陷阱会自动执行cleanup
Here Document
# 基本用法
cat << EOF
这是一个多行文本
第二行
第三行
EOF
# 变量替换
cat << EOF
用户: $USER
日期: $(date)
EOF
# 禁止变量替换
cat << 'EOF'
$USER 不会被替换
$(date) 也不会被替换
EOF
# 缩进处理
cat <<- EOF
这行有前导Tab
会被自动去除
EOF
正则表达式
# 使用 =~ 进行正则匹配
email="user@example.com"
if [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "有效邮箱"
fi
# 提取匹配内容
if [[ "Hello 123 World" =~ ([0-9]+) ]]; then
echo "数字: ${BASH_REMATCH[1]}"
fi
并发执行
#!/bin/bash
# 后台执行
sleep 5 &
PID1=$!
sleep 3 &
PID2=$!
# 等待所有后台任务
wait $PID1
echo "任务1完成"
wait $PID2
echo "任务2完成"
实践:批量文件处理
#!/bin/bash
# 批量重命名
for file in *.jpg; do
newname="photo_$(date -r "$file" +%Y%m%d)_${file}"
mv "$file" "$newname"
done
# 批量压缩
find . -name "*.log" -mtime +7 -exec gzip {} \;
# 批量查找大文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null
调试技巧
# 启用调试模式
bash -x script.sh
# 在脚本中启用
set -x
# 禁用调试
set +x
# 严格模式
set -euo pipefail
# -e: 命令失败时退出
# -u: 使用未定义变量时报错
# -o pipefail: 管道中任何命令失败则失败
总结
Shell脚本进阶技巧能够帮助你编写更加健壮、高效的自动化脚本。掌握数组、字符串处理、陷阱处理等特性,是成为高级运维工程师的必经之路。