sea shell, giant conch, cypraeacassis rufa

进阶 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

并行执行

对于可以同时进行的任务,可以考虑使用并行处理来加速。xargsGNU 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"

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注