我正在从 bash 脚本创建临时文件。我在处理结束时删除它们,但由于脚本运行了相当长的时间,如果我杀死它或在运行期间简单地按 CTRL-C,临时文件不会被删除。
有没有办法可以在执行结束之前捕获这些事件并清理文件?

另外,这些临时文件的命名和位置是否有某种最佳实践?
我目前不确定使用:

TMP1=`mktemp -p /tmp`
TMP2=`mktemp -p /tmp`
...

TMP1=/tmp/`basename $0`1.$$
TMP2=/tmp/`basename $0`2.$$
...

或者也许有一些更好的解决方案?

有帮助吗?

解决方案

您可以设置一个“陷阱”来执行上退出或在控制-C进行清理。

trap "{ rm -f $LOCKFILE; }" EXIT

另外,我最喜欢的UNIX的ISMS之一就是打开一个文件,然后删除它,而你仍然有它打开。该文件仍保留在文件系统上,你可以读,写,但只要你的程序退出时,该文件就会消失。不知道你会怎么做,在bash中,虽然。

BTW:有一种说法,我会赞成mktemp的,而不是使用自己的解决方案给:如果用户期待您的程序将创造巨大的临时文件,他可能要设置TMPDIR某处更大,如/ var / tmp中。 mktemp的认识到,你的手卷解决方案(第二个选项)没有。我经常使用TMPDIR=/var/tmp gvim -d foo bar,例如

其他提示

我通常会创建一个目录在其中放置我所有的临时文件,然后后,创建一个EXIT处理程序来清理这个目录的脚本退出时。

MYTMPDIR=$(mktemp -d)
trap "rm -rf $MYTMPDIR" EXIT

如果你把下$MYTMPDIR所有的临时文件,然后将他们全部当你的脚本退出在大多数情况下删除。终止进程与SIGKILL(杀死-9)杀死进程马上的,所以你的EXIT处理程序不会在这种情况下运行。

您想使用陷阱命令处理退出脚本或类似信号CTRL-C。请参阅 Greg的维基,获取的信息。

有关您的临时文件,使用basename $0是一个好主意,以及提供一个模板,足够临时文件提供了空间:

tempfile() {
    tempprefix=$(basename "$0")
    mktemp /tmp/${tempprefix}.XXXXXX
}

TMP1=$(tempfile)
TMP2=$(tempfile)

trap 'rm -f $TMP1 $TMP2' EXIT

只需记住,choosen答案是bashism,这意味着溶液

trap "{ rm -f $LOCKFILE }" EXIT

将只工作在bash(它不会赶上按Ctrl + c。如果壳dash或经典sh),但如果你想兼容,那么你仍然需要枚举要捕获所有的信号。

还要记住的是,当脚本退出为信号“0”(又名EXIT)陷阱总是执行导致trap命令的双重执行。

,之所以不堆叠的所有信号在一行中是否存在退出信号。

要更好地理解它看看下面的脚本,将在不同的系统工作,而无需改变:

#!/bin/sh

on_exit() {
  echo 'Cleaning up...(remove tmp files, etc)'
}

on_preExit() {
  echo
  echo 'Exiting...' # Runs just before actual exit,
                    # shell will execute EXIT(0) after finishing this function
                    # that we hook also in on_exit function
  exit 2
}


trap on_exit EXIT                           # EXIT = 0
trap on_preExit HUP INT QUIT TERM STOP PWR  # 1 2 3 15 30


sleep 3 # some actual code...

exit 

这个解决方案会给你更多的控制,因为你可以最终退出(preExit功能)前运行一些实际信号的出现你的代码,如果需要,您可以在实际的退出信号运行一些代码(出口的最后阶段)

使用带有 $$ 的可预测文件名的替代方案是一个巨大的安全漏洞,您永远不应该考虑使用它。即使它只是单用户 PC 上的一个简单的个人脚本。这是一个非常坏的习惯,你不应该养成这种习惯。 错误追踪 充满了“不安全的临时文件”事件。看 这里, 这里这里 有关临时文件安全方面的更多信息。

我最初考虑引用不安全的 TMP1 和 TMP2 分配,但转念一想,这可能会 这不是一个好主意.

我更喜欢使用tempfile其在安全的方式/ tmp中创建一个文件,你不必担心它的命名:

tmp=$(tempfile -s "your_sufix")
trap "rm -f '$tmp'" exit

您不必费心删除与mktemp的创建者。tmp文件。他们将反正后来被删除。

如果你可以因为它会产生更多的独特的文件,然后“$$”前缀使用mktemp的。它看起来像更多的跨平台的方式创建临时文件,然后明确地把它们放到/ tmp目录。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top