进阶 Shell 编程
原文:Advanced Shell Scripting Techniques: Automating Complex Tasks with Bash。本文是原文中「脚本优化」和「错误处理」两部分的中文翻译。
脚本优化
使用内置命令
使用 shell 内置命令往往效率更高,执行得更快。比如,尽量使用内置的 [[ ]]
做条件判断,不要用 [ ]
或 test
命令。
# Inefficient
if [ "$var" -eq 1 ]; then
echo "Equal to 1"
fi
# Efficient
if [[ "$var" -eq 1 ]]; then
echo "Equal to 1"
fi
尽量减少 subshell
创建子 shell 是比较耗费资源、性能的操作,尽量通过使用内置命令或参数展开等办法避免创建子 shell。
# Inefficient
output=$(cat file.txt)
# Efficient
output=$(<file.txt)
针对批量数据使用数组
要处理比较多的数据时,用数组比用多个变量更有效率,也更容易管理。
# Inefficient
item1="apple"
item2="banana"
item3="cherry"
# Efficient
items=("apple" "banana" "cherry")
for item in "${items[@]}"; do
echo "$item"
done
开启 noclobber
在脚本中启用 noclobber
可以阻止不小心覆盖某个文件(比如本来应该写 >>
追加文件符号,写成了 >
符号,noclobber
就会报错 cannot overwrite existing file
),在需要生成临时文件的场景中尤其有用。
set -o noclobber
使用函数
函数可以封装代码,提高代码的可复用性,让脚本更简洁,减少冗余。
function greet() {
local name=$1
echo "Hello, $name"
}
greet "Alice"
greet "Bob"
高效的文件操作
执行文件操作时,使用一些技巧让资源占用更少,性能更好。
# Inefficient
while read -r line; do
echo "$line"
done < file.txt
# Efficient
while IFS= read -r line; do
echo "$line"
done < file.txt
并行执行
对于可以同时进行的任务,可以考虑使用并行处理来加速。xargs
和 GNU parallel
这些工具非常有用。
# Using xargs for parallel processing
cat urls.txt | xargs -n 1 -P 4 curl -O
错误处理
出错时退出
使用 set -e
来保证脚本在出错时及时退出,而不是继续执行下去,从而阻止连锁(很可能是意料之外的)错误的发生。
set -e
自定义错误信息
命令出错时,输出更有价值、更便于分析错误的、自定义错误信息。
command1 || { echo "command1 failed"; exit 1; }
捕获信号
使用 trap
命令来捕获并且优雅地处理信号和错误。
trap 'echo "Error occurred"; cleanup; exit 1' ERR
function cleanup() {
# Cleanup code
}
校验输入
一定要校验用户的输入和脚本参数,阻止意料之外的行为。
if [[ -z "$1" ]]; then
echo "Usage: $0 <argument>"
exit 1
fi
日志
使用日志来跟踪脚本执行,诊断问题。
logfile="script.log"
exec > >(tee -i $logfile)
exec 2>&1
echo "Script started"