7

Quite often, we run an executable that needs to write / read some temporary files. We usually create a temporary directory, run the executable there, and delete the directory when the script is done.

I want to delete the directory even if the executable is killed. I tried to wrap it in:

#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
/usr/local/bin/my_binary

When my_binary dies, the last process the kernel will delete the directory, as the script is the last process holding that inode; but I can't create any file in the deleted directory.

#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
touch file.txt

outputs touch: file.txt: No such file or directory

The best I could come up with is to delete the temp directory when the process dies, catching the most common signals, and run a cleanup process with cron:

#!/bin/bash
dir=$(mktemp -d /tmp/d.XXXXXX) && cd "$dir" || exit 99
trap 'rm -rf "$dir"' EXIT
/usr/local/bin/my_binary

Is there some simple way to create a really temporary directory that gets deleted automatically when the current binary dies, no matter what?

  • 1
    beware that you have a small window where cleanup may be executed before the mktemp is done. You may want to unset dir before setting the trap. – Stéphane Chazelas Feb 18 '14 at 15:31
  • nice catch, I updated the script to handle this and to handle a failure in mktemp. – Joaquin Cuenca Abela Feb 18 '14 at 15:35
  • I thought that exit was mandatory. Fixed. – Joaquin Cuenca Abela Feb 18 '14 at 15:52
  • Your last example mentions cron, but has nothing to do with cron. That last example is also the most fail safe. The only thing it won't handle is SIGKILL. – Patrick Feb 19 '14 at 2:31
  • I didn't include the cron script that I'm running to keep it succint. It's a find over that pattern to match dirs older than 1 hour and rm them. I want to know if there is any solution that will also cover the sigkill case, or even a brutal shutdown in the middle of the script. – Joaquin Cuenca Abela Feb 19 '14 at 7:36
2

Your last example is the most fail safe.

trap 'rm -rf "$dir"' EXIT

This will execute as long as the shell itself is still functional. Basically SIGKILL is the only thing that it won't handle since the shell is forcibly terminated.
(perhaps SIGSEGV too, didn't try, but it can be caught)

If you don't leave it up to the shell to clean up after itself, the only other possible alternative is to have the kernel do it. This is not normally a kernel feature, however there is one trick you can do, but it has it's own issues:

#!/bin/bash
mkdir /tmp/$$
mount -t tmpfs none /tmp/$$
cd /tmp/$$
umount -l /tmp/$$
rmdir /tmp/$$

do_stuff

Basically you create a tmpfs mount, and then lazy unmount it. Once the script is done it'll be removed.
The downside other than being overly complex, is that if the script dies for any reason before the unmount, you've not got a mount laying around.
This also uses tmpfs, which will consume memory. But you could make the process more complex and use a loop filesystem, and remove the file backing it after it's mounted.


Ultimately the trap is best as far as simplicity and safety, and unless you're script is regularly getting SIGKILLed, I'd stick with it.

  • Does it matter if the trap is placed before the mktemp or after it? I would think if the trap is placed just before the mktemp, then even if the exit signal were received after the trap and before the mktemp, all that would happen is an rm -rf command would be run with an empty argument, accomplishing nothing. But if the trap were after the mktemp, there could be a tiny window of a chance that the temp dir would get left. Or am I completely off base? – Wildcard Jan 23 '16 at 4:58
0

You could use the wait builtin to wait for a background job to finish:

blah &
wait
rm -rf $DIR
  • But that will be equivalent to blah; rm -rf $DIR, right? It has the problem that it will leak $DIR if the script is killed. – Joaquin Cuenca Abela Feb 19 '14 at 11:04
  • If the child script is killed, the parent script will still be around to clean up after it. If the parent script is also killed, then yeah, the directory will be left behind. – Matthew Cline Feb 19 '14 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.