Do I need to check & create /tmp before writing to a file inside of it?
Assume that no one has run sudo rm -rf /tmp because that's a very rare case
3 Answers
The FHS mandates that /tmp exist, as does POSIX so you can rely on its being there (at least on compliant systems; but really it’s pretty much guaranteed to be present on Unix-like systems). But you shouldn’t: the system administrator or the user may prefer other locations for temporary files. See Finding the correct tmp dir on multiple platforms for more details.
-
This is of course a design failure.
/tmpis a name.$TMPDIRis another name. If you can't count on/tmpbeing the right name of the temporary directory, why can you count on$TMPDIRbeing the name of the right environment variable? Why shouldn't I check$TMPDIRVARto get the name of that variable? One level of indirection is sufficient, and/tmpis exactly that. It doesn't say anything about the actual storage, it's just a name.– MSaltersCommented May 2, 2017 at 9:47 -
1@MSalters there’s a bit more to it than that. Before namespaces,
$TMPDIRallowed each user to have a separate temporary directory, or even to use different temporary directories for different programs; a single/tmpdoesn’t provide that (again, without namespaces or something similar). There’s also a lot of history (or legacy) to take into account. Commented May 2, 2017 at 9:52 -
Per user is a valid point, but that is why a good design would use
~/tmpfor that. Which may still be the same physical location as/tmp, of course.– MSaltersCommented May 2, 2017 at 10:04
In practice, /tmp is pretty much guaranteed to exist. However, even if it exists, that doesn't mean you should put temporary files there.
The standard convention is to use the TMPDIR environment variable. If it exists, it points to a directory for temporary files. If it doesn't exist, put temporary files in /tmp.
In a shell script, you can use "${TMPDIR:-/tmp}" as the temporary file location: this expands to the value of TMPDIR if it's set¹, and to /tmp otherwise. Or you can set TMPDIR conditionally in case it's unset, with the command
: "${TMPDIR:=/tmp}"
and then create temporary files inside "$TMPDIR".
Note that any application can create files under /tmp or $TMPDIR. Furthermore this directory may be shared between users, so you need to take care about permissions when creating a file. Many systems (Linux, *BSD) have a command mktemp which creates files safely in the right directory. It's generally a good idea to use mktemp to create temporary files and directory — especially from a shell script, where it's impossible to create a file securely in a shared directory due to the possibility of symlink attacks (mkdir is fine if you handle errors correctly).
¹ and non-empty — if the variable is empty then it isn't usable as is anyway, and it's generally a good idea to treat empty or unset variables in the same way if they're supposed to contain a file name.
-
11Maybe you could mention that users have to expect file name collisions. So IMO the only recommended way to create files in /tmp is the command
mktempand this should also handle $TMPDIR" automatically. Commented Apr 29, 2017 at 13:22 -
This is the answer you want. I've seen systems without /bin let alone /tmp.– JoshuaCommented Apr 29, 2017 at 14:14
-
1Also A.10 Directory Structure and Devices states: ... The
/tmpdirectory 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 variableTMPDIRand applications are encouraged to use the contents ofTMPDIRfor creating temporary files. ... Commented Apr 29, 2017 at 14:35 -
3Just sad to find that
mktempis not in POSIX, although it's already in most popular operating systems like GNU (Linux), OpenBSD, FreeBSD, and macOS. Commented Apr 30, 2017 at 15:39 -
1
Although it's very likely to exist, you should check for another reason: it's not guaranteed to be big. On many systems, /tmp is backed by RAM rather than disk, and likely to be limited to a few GB. (On Fedora systems, it's half of RAM by default.) So, you should check not just for existence, but whether there's room to put whatever you intend to put there.
If you have something large, use /var/tmp/.
-
2I'm not sure if it is "the Unix way" to check available space before proceeding, especially since it is not always known exactly how much space you will need. In any case, you have to be prepared to handle a write error gracefully in case the filesystem should become full; and if you are going to do that, what is gained by doing an advance check that will be prone to false negatives and positives? Commented Apr 30, 2017 at 23:41
-
2Depends how gracefully you can handle the failure case, I guess. The main point is to not assume that
/tmpcan handle large files. Let's say it's a 10GB download over a moderate-speed link. "Unix way" or not, it's pretty miserable to find out several hours in that it's not going to work.– mattdmCommented May 1, 2017 at 13:21 -
1@mattdm Checking early is nice but failure has to be handled. Maybe /tmp does have 10 GB available when the download starts but Another User copies 5 GB into there while your download is running. Now What? Heh.– Zan LynxCommented May 1, 2017 at 17:17
-
Definitely! I don't mean this as an excuse to not handle failure.– mattdmCommented May 1, 2017 at 17:48
-
"If you have something large" - use /tmp and let the OS swap if it needs to.– UKMonkeyCommented Oct 16, 2018 at 15:09
/tmp(created withmktemp) then remove that subdirectory on exit. Most of my system is mounted read-only and this keeps me from having to remember tocdto a writable directorymktemplooks really great, i'l probably end using that./tmp. However, conversely it is allowed to do so, and presumably WGroleau has extrapolated too far from that. My/tmpis atmpfsheld in RAM, so it does get cleared on shutdown. Still, that's just a detail of the system, which isn't guaranteed by the FHS. So, to the original comment, it's folly to rely on the presence or absence of anything in/tmpbetween boots.