删除意外 bash 退出中创建的临时文件
-
22-08-2019 - |
题
我正在从 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处理程序不会在这种情况下运行。
只需记住,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
功能)前运行一些实际信号的出现你的代码,如果需要,您可以在实际的退出信号运行一些代码(出口的最后阶段)
我更喜欢使用tempfile
其在安全的方式/ tmp中创建一个文件,你不必担心它的命名:
tmp=$(tempfile -s "your_sufix")
trap "rm -f '$tmp'" exit
您不必费心删除与mktemp的创建者。tmp文件。他们将反正后来被删除。
如果你可以因为它会产生更多的独特的文件,然后“$$”前缀使用mktemp的。它看起来像更多的跨平台的方式创建临时文件,然后明确地把它们放到/ tmp目录。