使用 Bash trap 语句清理临时文件

作者:Mitch Frazier

bash 中的trap语句使您的脚本在接收到信号时执行一个或多个命令。 你可以使用它的一个有用的地方是在脚本退出时清理临时文件。

要在脚本接收到信号时执行代码,请使用以下语法

trap arg sigspec...

"arg" 是要执行的命令。如果命令包含空格,请用引号将其引起来。您可以通过用分号分隔来包含多个命令。对于更复杂的事情,将您的退出代码放在一个函数中并简单地调用该函数。"sigspec" 列表是要捕获然后执行 "arg" 的信号列表(如果/当它们发生时)。例如,要在退出时删除文件,请执行以下操作

trap "rm -f afile" EXIT

请注意,EXIT 不是一个真正的信号(执行kill -l查看所有信号);它是由 bash 合成的。

小心在 "arg" 中使用通配符,因为如果它们未用引号引起来或用双引号引起来,它们将在遇到 trap 语句时展开,而不是在执行 "arg" 时展开。例如,如果您有一个名为 "abc.tmp" 的文件并且执行了以下 trap 语句

trap "rm -f *.tmp" EXIT

脚本退出时执行的命令是 "rm -f abc.tmp" 而不是 "rm -f *.tmp"。要避免此问题,请使用单引号。

如果您在代码中的各个位置创建临时文件,并且您不使用命名约定,该约定允许您在 trap 语句中使用通配符,并且您不想担心随着代码的发展而更改 trap 语句,您可以编写如下内容,以允许您添加在退出时执行的新 trap 命令

#!/bin/bash

declare -a on_exit_items

function on_exit()
{
    for i in "${on_exit_items[@]}"
    do
        echo "on_exit: $i"
        eval $i
    done
}

function add_on_exit()
{
    local n=${#on_exit_items[*]}
    on_exit_items[$n]="$*"
    if [[ $n -eq 0 ]]; then
        echo "Setting trap"
        trap on_exit EXIT
    fi
}

touch $$-1.tmp
add_on_exit rm -f $$-1.tmp

touch $$-2.tmp
add_on_exit rm -f $$-2.tmp

ls -la

这里的函数add_on_exit()将命令添加到数组中,并且on_exit()函数循环遍历数组中的命令并在退出时执行它们。 on_exit 函数在第一次调用 add_on_exit 时设置为 trap 命令。

Mitch Frazier 是 Emerson Electric Co. 的一名嵌入式系统程序员。自 2000 年代初以来,Mitch 一直是 Linux Journal 的贡献者和朋友。

加载 Disqus 评论