Mktemp with suffix/extension

If you want to create a unique temporary file in a shell script, you would use the mktemp command. You can even specify a template where XXXXXX would be replaced by a unique combination. For instance:

mktemp ./my-temporary-file.XXXXXX

Now what happen if you want to create a temporary file ending with some particular suffix? You may want to do that because the program to which you feed your temp file expects some file extension to parse it properly. For example most web browsers expect files ending in .htm or .html to parse them as HTML documents. However, if you try to provide mktemp with a template ending with the appropriate suffix, that wouldn’t work (at least not on FreeBSD and OpenBSD):

mktemp /tmp/tmpXXXXXX.html

The version of mktemp in GNU coreutils comes with a --suffix option that allows you to do just that. But this is specific to GNU so you should not use that if you care about your scripts and other people. And please, do care about other people. Truly, scripts expecting /bin/sh to be bash or some other Linuxism are a real chore to work with, even if you work on Linux. So please restrain yourself and do the right thing.

A first solution that would come to mind would be to create the temporary file and move it to the same name but with the appropriate suffix, like this:

# Don't do that it's wrong!
mv "$tmp" "$tmp_html"

But this is wrong! So don’t do that. The problem is that when you move your file, you don’t know if another file with the name "$tmp_html" is already present. It may be very unlikely, but not impossible. You may want to check if the file exists before executing the move but you could never completely avoid a potential race condition that mktemp was supposed to fix.

So a more correct answer is to create a temporary directory, and create your file in it:

tmp_d=$(mktemp -d)

... do your things ...

rm -r "$tmp_d"

With this, you know that your directory is unique, and as long as you are the only person using it, any file created in it should be unique too.