Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I'm looking at a bash script someone else wrote that uses mktemp:

TEMP=`mktemp --directory`

However, this line does not work on my machine (OS X 10.6).

How would I fix this line so that it is cross-un*x-like-platform compatible? EDIT: An alternative command would be sufficient as well.

share|improve this question

4 Answers 4

up vote 10 down vote accepted

You have to supply a template. mktemp -d /tmp/foo.XXXX should work. I've never seen --directory. The -- suggests that it is a GNU extension.

share|improve this answer
If you want to use $TMPDIR when available, do mktemp -d "${TMPDIR:-/tmp}"/foo.XXXX. That works in bash on the Mac and dash on Debian, so it seems portable. – Tom Anderson Apr 15 at 7:36

The following is what I ended up using to reliably create a temporary directory that works on both Linux and Darwin (Mac OS X), without hardcoding $TMPDIR or /tmp:

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`


The GNU mktemp command requires no arguments. Plain mktemp will create a temporary file in the system temporary directory.

Plain mktemp -d will create a temporary directory, which is what you'd want to use on Linux.

(gnu-coreutils)$ man mktemp
# If DIR is not specified, uses $TMPDIR if set, else /tmp.

By default it uses template tmp.XXXXXXXXXX expanded relative to the default temporary directory.

OSX's mktemp command requires this template, it has no default. The syntax for the template on OSX is compatible with that of GNU's. OSX's mktemp has a -t option that means something else. The -t option is documented as "prefix". It is expanded to $TMPDIR/{prefix}.XXXXXXXX, so it adds the Xs to it automatically (e.g. mktemp -d -t example could create $TMPDIR/example.zEJZWCTQ).

I was surprised to find that in various Linux environments $TMPDIR is not set by default (many tools support it when set, but still have to default to /tmp). Which meant passing $TMPDIR/example.XXXXXXXX to mktemp or mkdir was not an option (as it would cause the path to end up as a subdirectory of the root directory).

On OSX $TMPDIR is always set and (at least in the default shell) it is not set to /tmp (which is a symlink to /private/tmp) but to /var/folders/dx/*****_*************/T. So we should honour that if we can.

In conclusion the following is what I ended up using to reliably create a temporary directory that works on both Linux and Darwin (Mac OS X), without hardcoding $TMPDIR or /tmp:

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

The first part is for Linux. This command will fail on Darwin (Mac OS X) with error status code 1 responding with "usage: ...". That's why we ignore stderr and instead then execute the Mac variant. The mytmpdir prefix is only used on Mac.

share|improve this answer
Really cool. Sometimes OS X different behaviour is annoying. – therealmarv Aug 22 '13 at 9:55
@therealmarv I'd rather say, always. – Nikita Volkov Nov 26 '13 at 18:44
This really should be the accepted answer... so great. – delfuego Jul 22 '14 at 20:56
this answer is much better than the chosen one – Mauro Feb 17 at 0:19

Change --directory to -d. The former is a GNU-ism, but GNU mktemp from coreutils also supports -d. The mktemp in OS X is the same as from BSD, so -d should be pretty portable among systems that actually ship a mktemp program.

share|improve this answer
I just tried mktemp -d, and it does not work either. – mindeavor. Jan 26 '12 at 19:56
Kyle has the complete answer. The mktemp on OS X requires a template. The script you're using assumes GNU conventions, which uses a default template if none is supplied. – James Sneeringer Jan 26 '12 at 21:24
temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX")"
  • mktemp for BSD (including OSX) requires a template, but it allows any number of Xs in the template.
  • (GNU) mktemp for Linux does not require a template, however, if a template is specified, then the number of Xs must be 6.

Note that -t is deprecated for GNU mktemp, so a more future-proof code would be

temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX" 2>/dev/null || mktemp -q -d)"
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.