📅 January 19, 2024
“How can I create a temporary file for noncritical stuff when running a bash script?”
Easy!
The built in mktemp command creates a 100% unique file or directory where you can store temporary data or whatever you need for your script.
mktemp
No need to install mktemp — it is already present in Bash.
Linux provides a dedicated directory for temporary data. /tmp is available to all users on the system, and anyone can read and write its contents.
By default, mktemp by itself will create a temporary file with a name of random characters similar to tmp.dOJ23yYkB8 in the /tmp directory.
mktemp
Result
/tmp/tmp.dOJ23yYkB8
mktemp returns the generated path for capture in a variable in case you need it.
Unique Filename
The most useful feature of mktemp is that it will generate a random filename that does not conflict with any other filename or directory. You can be certain that you have a filename unique to your script without the risk of clobbering another file.
Another way to create a temporary file in the /tmp directory is to use the -t option.
mktemp -t gigglebear.XXXXXXXX
This creates the file in /tmp.
/tmp/gigglebear.QstCCwJZ
By doing this, we can customize the prefix from tmp to gigglebear or whatever we want.
/tmp Access Rights
Just because any user can access /tmp contents does mean users can trample upon each other’s temporary files. Only the user/process that created the temporary file is allowed to read and write it (unless permissions are changed).
An example
-rw------- 1 user user 0 Jan 18 08:06 tmp.dOJ23yYkB8
By default, the temporary file was created in /tmp with rw- permissions for the owner only. All other users are denied access. This is a good thing because we do not others modifying or viewing our temp data during the script execution. It helps increase privacy.
Creating a Local Temporary File
Maybe we do not want to create a temporary file in /tmp. How about the same directory where the script is running?
mktemp tempfile.XXXXX
This is a template that tells mktemp to produce a file in the current directory.
tempfile.Y8sr8
When we specify the filename, this file will be created in the current directory, not /tmp. tempfile is just a name that we make up, and the XXXXX tells mktemp to replace the X’s with random uppercase, lowercase, and number characters up to five in a sequence. The more X’s we include, the more random the filename will be.
mktemp gigglebear.XXXXXXXXX gigglebear.FXl1ZVJ1E
mktemp porridge.XXXXXXXXXXXXXXXXXXXX porridge.7YrKbEotzWPNiGf9Z5lp mktemp goldilocks.X mktemp: too few X's in template ‘goldilocks.X’
(We need at least three X’s.)
In fact, we do not need to precede the filename with anything custom, Just use X’s like this:
mktemp XXXXXXXXXXX
And you will get an empty file with a random filename:
Z7dtY0yy5ze
In practice, it is a good idea to add some kind of unique leading name to make it easier to identify as being generated by a particular script. Please, oh please, avoid naming temporary files as Untitled:
mktemp Untitled1.XXXX Untitled1.XqMP
This is Linux, not Windows.
Creating a Temporary Directory
mktemp is not limited to files — we can create temporary directories too using the -d option!
mktemp -d winterbreeze.XXXXXX
This creates a directory named
winterbreeze.z82IzU
in the current directory. If we want to create a temporary subdirectory in /tmp, then we combine it with the -t option.
mktemp -dt winterbreeze.XXXXXX
/tmp/winterbreeze.l6yLgZ
This is usually a good idea so you can keep your temporary files contained within a single location for easier deletion.
Deleting a Temporary File
If you have been following along, you will notice that mktemp always returns the path of the file created. We can capture this in a variable in order to delete the temporary file later after before the script exits in order to avoid littering the current path or /tmp directory. Temporary files/directories that we create do not delete themselves. We must write this into the script. Here is an example:
test.sh
#!/bin/bash temp=$(mktemp data.XXXX) echo "$temp" sleep 3 rm "$temp"
We use command substitution $(mktemp data.XXXX) to create the temporary file and then capture the return path into a variable named temp. Now that we have the path stored in $temp, we can remove it later using the rm command. (In the example script above, all we do is echo $temp so we can see that it has been saved to a variable.)
If you watch the directory when this script executes, you will see the temporary file is created and then deleted after three seconds to simulate activity. Once we have our temporary file, we can treat it like any other file in the script.
Deleting a Temporary Directory
Directories are handled a little differently when deleting since they must be empty first. Rather than keep track of each file, we can forcefully remove a directory even if it contains files using the -rf option for rm. However, be careful since this runs a forced recursive delete on the directory.
Technique 1: Forced Recursive Delete
#!/bin/bash temp=$(mktemp -d data.XXXX) for i in $(seq 1 10) do touch $temp/$(mktemp "junk${i}.XXXXX") done echo "$temp" sleep 10 rm -rf "$temp"
After ten seconds, enough time to navigate to the new subdirectory to view its generated contents, the entire temporary directory and its files will be deleted. Again, be careful whenever using rm -rf to make absolutely certain that you are deleting the correct directory since you can lose precious data if careless. And NEVER use this rm -rf with sudo to be safe.
Technique 2: Delete Files One By One
A safer option is to add code to recursively find all files in the temporary subdirectory and delete them one by one.
#!/bin/bash
temp=$(mktemp -d data.XXXX)
for i in $(seq 1 10)
do
touch $temp/$(mktemp "junk${i}.XXXXX")
done
echo "$temp"
sleep 10
echo "Removing $temp"
for f in $temp/*
do
echo "Removing $f"
rm "$f"
done
rmdir "$temp"
This adds extra code to the script, but it is safer.
“How do I delete temporary files and directories that already exist?”
You will need to do this manually since mktemp only creates temporary files. It does not remove them. You must develop your own solution to delete temporary data. This is why it is best to allow your script to clean up after itself by deleting temporary files before it exits. Otherwise, it is easy to clutter directories. The only solution is to manually remove residual files and directories no longer needed.
Conclusion
mktemp is handy to use because it generates a filename or directory with a unique name in the given path. We can also customize the length of the filename with a custom part and a random part if we wish. If you find yourself needing a way to store temporary data in a file, then give mktemp a try.
Have fun!