在bourne shell脚本结束时删除临时文件

时间:2013-04-17 19:56:57

标签: shell sh temporary-files shell-trap

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

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

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

我该怎么做?

1 个答案:

答案 0 :(得分: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} expansions in every 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

# ...