Twitter

Some bash tips -- 1 -- Use mktemp for your tempfiles

This blog is part of a bash tips list I find useful to use on every script -- the whole list of it can be found here.

Tempfiles are very oftenly used when scripting for storing temporary information. Many people generate tempfiles names like this:
$ TMP="/tmp/tempfile$$"
$$ being the OS process ID which is unique during its timelife and can be reused at some point by the OS. The issue with this way of naming the tempfiles is that you cannot prevent someone/something else to create a file (temporary or not) with the same names as yours like
$ TMP="/tmp/tempfile1234"
and you will be in trouble when your PID will be "1234". This is a very basic example indeed but many things can happen on a system preventing this way of creating a tempfile from being robust (more on this in the official documentation).

The robust way of creating a tempfile is by using the mktemp command which works as below:
$ mktemp
/tmp/tmp.ux4B5I6HbU
$  ls -ltr /tmp/tmp.ux4B5I6HbU
-rw------- 1 fred fred 0 Aug 12 10:50 /tmp/tmp.ux4B5I6HbU
$ 
You can see that mktemp creates an empty temporary file and returns its name; easy peasy. You can easily use it like this:
$ TMP=$(mktemp)
$ echo ${TMP}
/tmp/tmp.Q1cYlGV4rG
$ ls > ${TMP}
You can also not create the file and just get its name which is less secure but still you can do it:
$ TMP=$(mktemp -u)
$ echo ${TMP}
/tmp/tmp.XpLMjWKA7P
$ ls -l /tmp/tmp.XpLMjWKA7P
ls: cannot access '/tmp/tmp.XpLMjWKA7P': No such file or directory
The -d option is there if you want to create a temporary directory (and not a file):
$ mktemp -d
/tmp/tmp.ICTMO415iz
$  du -sh /tmp/tmp.ICTMO415iz
0       /tmp/tmp.ICTMO415iz
$  ls -ltr /tmp/tmp.ICTMO415iz
total 0
$ 
By default, mktemp will create temporary files and directories into /tmp as it is writeable by everyone; You can change this by setting the TMPDIR variable:
$ export TMPDIR="/home/fred"
$ mktemp
/home/fred/tmp.CxXIs2bze1
$ 
Option -p has the same effect:
$ mktemp -p "/home/fred"
/home/fred/tmp.FhJZ4JFfKb
$ 
If for any reason, you would like to name a part of the file yourself, you can provide a "template" with the -t option, and the number of X are for mktemp to generate a random pattern:
$  A_DATE=$(date +%Y%m%d_%H%M%S)
$  mktemp -p "/home/fred" -t "mytempfile_${A_DATE}_XXXXXXX"
/home/fred/mytempfile_20200820_140025_1dQTT3I
$ 
And the same example as above with the name of the tempfile in a variable for future use:
$  A_DATE=$(date +%Y%m%d_%H%M%S)
$  MYTEMPFILE=$(mktemp -p "/home/fred" -t "mytempfile_${A_DATE}_XXXXXXX")
# You can now use the tempfile as below:
$ some_commands >> "${MYTEMPFILE}"

This is already the end of the presentation of mktemp I strongly recommend to be using, enjoy !


< bash tip Menu / Next bash tip >

2 comments:

  1. Nice post. I didn't know about it.

    ReplyDelete
  2. Great 👍 thanks for sharing. Learnt something New. Please keep publishing

    ReplyDelete

Some bash tips -- 18 -- paste

This blog is part of a shell tips list which are good to know -- the whole list can be found here. I really like finding a real usage for...