/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/
This is your Darwin user local directory. Its name is simply a modified base 32 encoding of the concatenation your MacOS User UUID and your MacOS (BSD) user ID. The first two letters of the encoding are used as a "bucket" system to attempt to keep directory sizes low. Those two characters are the encoded first 10 bits of the User UUID, because in base 32 one digit is of course 5 bits.
Its subdirectories are your user local temp and user local cache directories. Their names used to be -Caches-
and -Tmp-
but those have been shortened to C
and T
. It should be apparent that all of these names are fixed and unchangeable, unless you are willing to change your user ID or user UUID.
When an application calls confstr(_CS_DARWIN_USER_TEMP_DIR,…)
, the C library first tries to ensure that you have a user local directory, then tries to ensure that you have a user local temp directory within it.
Ensuring that you have a user local directory is non-trivial, because you do not have write access to /var/folders
. So there is a dirhelper
Mach launch dæmon that runs with superuser privileges and that securely creates these directories, responding to Mach IPC calls from applications from within the implementation of confstr()
in their C libraries. You do have write access to the user local directory (once created) and so the C libraries just mkdir()
its children directly if they do not already exist.
If this succeeeds, the mktemp
program never looks at the value of the TMPDIR
environment variable, because the fallback in mktemp
's code is from calling confstr()
to calling getenv()
not the other way around. confstr(_CS_DARWIN_USER_TEMP_DIR,…)
will almost always succeed. Its failure modes are things like the dirhelper
launch dæmon not being able to be run, or the attempt to create the T
subdirectory failing with an error other than that the directory already exists.
You could put something other than a directory as T
, but this will be regularly cleaned up by the dirhelper
launch dæmon, which is also what deletes stuff in /var/folders
. Disabling the dirhelper
launch dæmon will cause problems of its own, not the least of which will be /var/folders
not getting cleaned. Denying yourself write permission on your user local directory will potentially interfere with all other uses of it, it being used for more than just a T
subdirectory.
Your best option (aside from supplying a template) is to make T
a symbolic link, but this is still far from good because it will of course affect all running applications of yours that might, at the very same instant, be wanting to create a temporary file.
Neither DARWIN_USER_TEMP_DIR
nor _CS_DARWIN_USER_TEMP_DIR
are variable names. They are names, for the getconf
utility and for the confstr()
library function, of a configuration string.
Best Answer
To safely create a temporary directory in the current directory, with a name that is not already taken, you can use
mktemp -d
like so:The
mktemp -d
command will create a directory at the given path, with theX
-es at the end of the pathname replaced by random alphanumeric characters. It will return the pathname of the directory that was created, and we store this value intmpdir
.1This
tmpdir
variable could then be used when following the same procedure that you are already doing, withbar
replaced by"$tmpdir"
:The
unset tmpdir
at the end just removes the variable.1 Usually, one should be able to set the
TMPDIR
environment variable to a directory path where one wants to create temporary files or directories withmktemp
, but the utility on macOS seems to work subtly differently with regards to this than the same utility on other BSD systems, and will create the directory in a totally different location. The above would however work on macOS. Using the slightly more convenienttmpdir=$(TMPDIR=$PWD mktemp -d)
or eventmpdir=$(TMPDIR=. mktemp -d)
would only be an issue on macOS if the default temporary directory was on another partition and thefoo
directory contained a lot of data (i.e. it would be slow).