0

我尝试使用trap在 Bourne shell 脚本末尾删除一个临时文件,但这不起作用:

trap "trap \"rm \\\"$out\\\"\" EXIT INT TERM" 0

顺便说一句,这是在函数内部,因此尝试嵌套陷阱。

我该怎么做?

4

1 回答 1

2

您只能为每个信号设置一个陷阱。如果脚本的不同部分需要执行不同的清理操作,则必须创建清理操作列表。然后设置一个单独的陷阱处理程序来执行所有必需的清理操作。

这是一个例子:

set -xv

PROG="$(basename -- "${0}")"

# set up your trap handler

TEMP_FILES=()

trap_handler() {
    for F in "${TEMP_FILES[@]}"; do
        rm -f "${F}"
    done
}

trap trap_handler 0 1 2 3 15

something_that_uses_temp_files() {
    mytemp="$(mktemp -t "${PROG}")"
    TEMP_FILES+=("${mytemp}")

    date > "${mytemp}"

    # ...
}

# ...

something_that_uses_temp_files

# ...

有一个陷阱处理程序,但您可以通过附加到TEMP_FILES数组从脚本中的任何位置注册清理操作。清理动作也可以从内部函数中注册。


如果你不使用带数组的 shell,基本思想是一样的,但实现细节会有点不同。例如,您可以将列表存储为以冒号分隔的字符串变量,使用${parameter%%word}每个 POSIX shell 中的扩展来遍历陷阱处理程序中的元素:

#!/bin/sh

set -xv

PROG="$(basename -- "${0}")"

# set up your trap handler

TEMP_FILES=""

trap_handler() {
    while [ -n "${TEMP_FILES}" ]; do
        CUR_FILE="${TEMP_FILES%%:*}"
        TEMP_FILES="${TEMP_FILES#*:}"
        if [ "${CUR_FILE}" = "${TEMP_FILES}" ]; then
            # there were no colons -- CUR_FILE is the last file to process
            TEMP_FILES=""
        fi

        if [ -n "${CUR_FILE}" ]; then
            rm -f "${CUR_FILE}"
        fi
    done }

trap trap_handler 0 1 2 3 15

something_that_uses_temp_files() {
    mytemp="$(mktemp -t "${PROG}")"
    TEMP_FILES="${TEMP_FILES}:${mytemp}"

    date > "${mytemp}"

    # ... }

# ...

something_that_uses_temp_files
something_that_uses_temp_files

# ...
于 2013-04-17T23:34:02.760 回答