19

I heard about $TEMP and $TMP, but I think they are not standard for every distro.

As far as I know, the best way to get the temp dir is just /tmp, is there any distro that won't work using that path?

3

3 Answers 3

29

$TMPDIR is more standard than both $TEMP and $TMP as it's mentioned by the POSIX standard.

The /tmp directory is retained in POSIX.1-2008 to accommodate historical applications that assume its availability. Implementations are encouraged to provide suitable directory names in the environment variable TMPDIR and applications are encouraged to use the contents of TMPDIR for creating temporary files.

Ref: http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap10.html

At least on macOS, $TMPDIR is not set to /tmp by default, but to something like /var/folders/4r/504v61kx02gczk_454db345c0000gn/T/. /tmp is still available though, as a symbolic link to /private/tmp (for whatever reason).

You may use tmpdir="${TMPDIR:-/tmp}" in a script, for example, to use $TMPDIR if it's set, or /tmp if it's not set (or empty).

The non-standard mktemp utility will create a file or directory in $TMPDIR by default and output its name (but not on macOS, see below):

tmpfile=$(mktemp)
tmpdir=$(mktemp -d)

Check the manual for mktemp on your system to figure out how to use it. Not all implementations are the same.


On macOS, because of reasons, you will have to give the mktemp utility a template with an explicit path:

tmpfile=$(mktemp "${TMPDIR:-/tmp}"/tmp.XXXXXXXX)
tmpdir=$(mktemp -d "${TMPDIR:-/tmp}"/tmp.XXXXXXXX)

The above commands would create a temporary file and directory (respectively) in $TMPDIR, or in /tmp if $TMPDIR is empty or if the variable is unset (this variable is by default set to the result of getconf DARWIN_USER_TEMP_DIR on macOS).


On Cygwin, $TMPDIR is not set by default:

$ echo $TMPDIR


$ echo $TEMP
/tmp

$ echo $TMP
/tmp

Consider using ${TMPDIR:-${TEMP:-${TMP:-/tmp}}} instead.

13
  • Yes, you beat me by seconds. $TMPDIR is far more known than $TEMP or $TMP Commented Mar 17, 2017 at 13:29
  • 5
    @cuonglm What? POSIX says (of its standard utilities) “If applications are written to use temporary or intermediate files, they should use the TMPDIR environment variable, if it is set and represents an accessible directory, to select the location of temporary files.” How is that not standard? Commented Mar 17, 2017 at 13:48
  • 2
    @cuonglm that’s a direct copy/paste from the standard. Commented Mar 17, 2017 at 13:59
  • 2
    nitpick: ${TMPDIR:-/tmp} would still be expanded to /tmp if $TMPDIR was set but to the empty string. One might argue that an empty $TMPDIR could be regarded as meaning the current directory, but IMO, it's better to consider an empty $TMPDIR as if it was unset and force users to specify the current directory with TMPDIR=., and that avoids having to do things like ${TMPDIR-/tmp}${TMPDIR:+/}file.tmp.$$ Commented Mar 17, 2017 at 14:07
  • 1
    See also echo 'mkstemp(TEMPLATE)' | m4 -D TEMPLATE="${TMPDIR:-/tmp}/prefixXXXXXX" for a standard way to create a temp file. Commented Mar 17, 2017 at 14:26
3

NOTE: The OPs question is "Generic way to get temp path?"; it is not "How to create a temp file/dir?"

The Linux man page for mktemp includes these options:

mktemp [OPTION]... [TEMPLATE] 
...
-u, --dry-run
    do not create anything; merely print a name
... 
--tmpdir[=DIR]
    interpret TEMPLATE relative to DIR. If DIR is not specified, 
use $TMPDIR if set, else /tmp. With this option, TEMPLATE must 
not be an absolute name. Unlike with -t, TEMPLATE may contain 
slashes, but mktemp creates only the final component. 

Therefore, either of the following are equivalent and should work:

dirname $(mktemp -u --tmpdir)

or

echo ${TMPDIR:-/tmp}

It's possible to imagine that the former might work while the latter doesn't on systems where either TMPDIR or /tmp are not used, but that have implemented the mktemp spec, albeit with a different explanation under the --tmpdir[=DIR] option. (However I am presently unable to test.)

0

I recommend a more comprehensive approach by checking all the possible env's that could be set. Also, let's not forget the XDG Base Directory specification by checking the XDG_RUNTIME_DIR.

https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

echo ${XDG_RUNTIME_DIR:-${TMPDIR:-${TMP:-${TEMP:-/tmp}}}}

This will most likely return /run/user/1000 for a system following XDG Base Directory, and if not, will check TMPDIR, TMP, and TEMP in order. If nothing is set, then it will return /tmp.

1
  • 2
    Reading that specification, it seems that $XDG_RUNTIME_DIR is mainly for small files such as PID files, sockets, etc. It explicitly says that it is not to be used for "large files", which is what the temporary directory is often used for. It also says that if the $XDG_RUNTIME_DIR can not be used, a message should be printed to warn the user of this fact before selecting another directory. That is if you want to follow that standard.
    – Kusalananda
    Commented Jan 11, 2022 at 10:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .