Delete created temporary files in unexpected bash output

I am creating temporary files from a bash script. I delete them at the end of processing, but since the script runs for quite a while, if I kill it or just CTRL-C during the run, temporary files are not deleted.
Is there a way to catch these events and clear the files before completion?

Also, is there any good practice for naming and placing these temporary files?
Currently, I am not sure between using:

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

and

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

Or maybe there are some better solutions?

+58
linux bash temporary-files
Mar 26 '09 at 18:28
source share
7 answers

You can set " trap " to execute on exit or using the -c control to clear.

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

Alternatively, one of my favorite unix-isms is to open the file and then delete it while you are still opening it. The file remains in the file system and you can read and write it, but as soon as your program exits, the file disappears. Not sure how you would do this in bash.

BTW: I will give one argument in favor of mktemp instead of your own decision: if the user expects your program to create huge temporary files, he may want to install TMPDIR somewhere more, for example / var / TMP. mktemp recognizes that your manual solution (second option) does not. I often use TMPDIR=/var/tmp gvim -d foo bar , for example.

+52
Mar 26 '09 at 18:32
source share

I usually create a directory to host all of my temporary files, and then immediately after that I create an EXIT handler to clear that directory when the script exits.

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

If you put all your temporary files in $MYTMPDIR , then all of them will be deleted when your script exits in most cases. Killing a process with SIGKILL (kill -9) immediately kills the process, so your EXIT handler will not work in this case.

+86
Mar 26 '09 at 18:42
source share

You want to use the trap command to handle exit from a script or signals like CTRL-C. See the Advanced Bash Scripting Guide for more details.

For your tempfiles, it is recommended that you use basename $0 , and also provide a template that provides space for enough temporary files:

 tempfile() { tempprefix=$(basename "$0") mktemp /tmp/${tempprefix}.XXXXXX } TMP1=$(tempfile) TMP2=$(tempfile) trap 'rm -f $TMP1 $TMP2' EXIT 
+16
Mar 26 '09 at 18:34
source share

An alternative to using the predicted $$ filename is a gaping security hole, and you should never think about using it. Even if it is a simple personalized script on your PC with one user. This is a very bad habit that you should not get. BugTraq is filled with "unsafe temporary file" incidents. See here , here and here for more information on the security aspect of temporary files.

I initially thought about quoting the unsafe assignments of TMP1 and TMP2, but secondly, I thought it probably wouldn't be a good idea .

+3
Mar 28 '09 at 23:35
source share

Just keep in mind that the selected answer is bashism , which means a solution like

 trap "{ rm -f $LOCKFILE }" EXIT 

will only work in bash (it will not catch Ctrl + c if the shell is dash or classic sh ), but if you need compatibility, you still need to list all the signals you want to capture.

Also keep in mind that when a script exits the trap for the signal "0" (aka EXIT), it always executes, which leads to a double execution of the trap command.

In order not to set all signals in one line, if there is an EXIT signal.

To better understand this, see the following script, which will work on different systems without changes:

 #!/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 

This solution will give you more control, since you can run some of your code when the actual signal appears just before the final exit ( preExit function), and if necessary, you can run some code with the actual EXIT signal (final stage of exit)

+3
Jan 9 '17 at 19:57
source share

I prefer to use tempfile , which creates the file in / tmp in a safe manner, and you do not need to worry about its name:

 tmp=$(tempfile -s "your_sufix") trap "rm -f '$tmp'" exit 
+1
Jul 21 '11 at 9:35
source share

You do not need to worry about deleting these tmp files created with mktemp. They will be deleted anyway later.

Use mktemp if you can, as it generates more unique files and then the $$ prefix. And this seems like a more cross-platform way to create temporary files and then explicitly put them in / tmp.

-four
Mar 26 '09 at 18:33
source share



All Articles