Finding the correct tmp dir on multiple platforms
A slightly more portable way to handle temporary files is to use mktemp
. It'll create temporary files and return their paths for you. For instance:
$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P
You could use it in a script quite easily:
tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile
Reading the man page, you should be able to set options according to your needs. For instance:
-d
creates a directory instead of a file.-u
generates a name, but does not create anything.
Using -u
you could retrieve the temporary directory quite easily with...
$ tmpdir=$(dirname $(mktemp -u))
More information about mktemp
is available here.
Edit regarding Mac OS X: I have never used a Mac OSX system, but according to a comment by Tyilo below, it seems like Mac OSX's mktemp
requires you to provide a template (which is an optional argument on Linux). Quoting:
The template may be any file name with some number of "Xs" appended to it, for example
/tmp/temp.XXXX
. The trailing "Xs" are replaced with the current process number and/or a unique letter combination. The number of unique file names mktemp can return depends on the number of "Xs" provided; six "Xs" will result in mktemp selecting 1 of 56800235584 (62 ** 6) possible file names.
The man page also says that this implementation is inspired by the OpenBSD man page for mktemp
. A similar divergence might therefore be observed by OpenBSD and FreeBSD users as well (see the History section).
Now, as you probably noticed, this requires you to specify a complete file path, including the temporary directory you are looking for in your question. This little problem can be handled using the -t
switch. While this option seems to require an argument (prefix
), it would appear that mktemp
relies on $TMPDIR
when necessary.
All in all, you should be able to get the same result as above using...
$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))
Any feedback from Mac OS X users would be greatly appreciated, as I am unable to test this solution myself.
If you're looking for the same thing in fewer lines...
for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
test -d "$TMPDIR" && break
done
You could write this in one.
You might do:
: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit
The shell should either find an executable directory in one of the 4 alternatives or exit with a meaningful error. Still, POSIX defines the $TMPDIR
variable (for XCU systems):
TMPDIR
This variable shall represent a pathname of a directory made available for programs that need a place to create temporary files.
It also requires the /tmp
path.