43

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

Ayush
  • 4,867
  • 16
    What do you mean by "guaranteed"? The FHS requires it, so any FHS-compliant distro would have it. However, there are many special purpose distros that are not FHS-compliant. It's certainly possible to create a Unix/Linux distro without /tmp, but whether you need to care about that entirely depends on whether you care about supporting those systems. – Lie Ryan Apr 29 '17 at 15:16
  • 1
    Why not create your own temporary dir and delete it when you're done with it instead of relying on the next reboot to clean up? – WGroleau Apr 29 '17 at 17:35
  • 4
    @WGroleau I don't know about OP, but on scripts I write for my own system, I usually put temp files in a subdirectory of /tmp (created with mktemp) then remove that subdirectory on exit. Most of my system is mounted read-only and this keeps me from having to remember to cd to a writable directory – Fox Apr 29 '17 at 18:10
  • 1
    @WGroleau I'm not relying on reboots to clean it up. the mktemp looks really great, i'l probably end using that. – Ayush Apr 29 '17 at 18:23
  • 1
    @Ayush Shanker: A good thing, too, because rebooting does not clean up /tmp. Mine has files & subdirectories going back a year or so, since the last time I manually cleaned it. – jamesqf Apr 29 '17 at 18:53
  • 7
    @jamesqf Yeah, rebooting is not required to clear /tmp. However, conversely it is allowed to do so, and presumably WGroleau has extrapolated too far from that. My /tmp is a tmpfs held 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 /tmp between boots. – underscore_d Apr 29 '17 at 19:49
  • @AyushShanker you could always mount /tmp as tmpfs in RAM... https://unix.stackexchange.com/a/55776/62481 – 0xSheepdog May 22 '17 at 20:41
  • Do not write directly to /tmp, use an os/environment supplied function, otherwise you're just asking for security/atomicity problems. Read the supplied documentation for the function you use to determine whether you or the OS is responsible for cleanup. – user12439 Sep 17 '18 at 01:07

3 Answers3

61

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.

Stephen Kitt
  • 434,908
  • This is of course a design failure. /tmp is a name. $TMPDIR is another name. If you can't count on /tmp being the right name of the temporary directory, why can you count on $TMPDIR being the name of the right environment variable? Why shouldn't I check $TMPDIRVAR to get the name of that variable? One level of indirection is sufficient, and /tmp is exactly that. It doesn't say anything about the actual storage, it's just a name. – MSalters May 02 '17 at 09:47
  • 1
    @MSalters there’s a bit more to it than that. Before namespaces, $TMPDIR allowed each user to have a separate temporary directory, or even to use different temporary directories for different programs; a single /tmp doesn’t provide that (again, without namespaces or something similar). There’s also a lot of history (or legacy) to take into account. – Stephen Kitt May 02 '17 at 09:52
  • Per user is a valid point, but that is why a good design would use ~/tmp for that. Which may still be the same physical location as /tmp, of course. – MSalters May 02 '17 at 10:04
48

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.

  • 11
    Maybe 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 mktemp and this should also handle $TMPDIR" automatically. – rudimeier Apr 29 '17 at 13:22
  • This is the answer you want. I've seen systems without /bin let alone /tmp. – Joshua Apr 29 '17 at 14:14
  • 1
    Also A.10 Directory Structure and Devices states: ... 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. ... – Andrew Henle Apr 29 '17 at 14:35
  • @AndrewHenle FYI beside $TMPDIR there are also other techniques to provide private /tmp directories per user or even per process (e.g. "Linux name spaces" https://blog.famzah.net/2014/06/04/private-tmp-mount-per-process-in-linux/, systemd based distros use that already). This should not change anything but you can not rely that /tmp is useful to share files between different users or services. – rudimeier Apr 29 '17 at 19:15
  • 3
    Just sad to find that mktemp is not in POSIX, although it's already in most popular operating systems like GNU (Linux), OpenBSD, FreeBSD, and macOS. – Franklin Yu Apr 30 '17 at 15:39
  • 1
    Might be worth adding that mktemp-like functions are available in many scripting and programming languages, such as libc, Perl and Python. – Gaurav May 01 '17 at 22:36
6

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/.

mattdm
  • 40,245
  • 2
    I'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? – Nate Eldredge Apr 30 '17 at 23:41
  • 2
    Depends how gracefully you can handle the failure case, I guess. The main point is to not assume that /tmp can 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. – mattdm May 01 '17 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 Lynx May 01 '17 at 17:17
  • Definitely! I don't mean this as an excuse to not handle failure. – mattdm May 01 '17 at 17:48
  • "If you have something large" - use /tmp and let the OS swap if it needs to. – UKMonkey Oct 16 '18 at 15:09
  • @UKMonkey Depending on how large. Many people don't have 10GB of swap, and very very few 100GB. – mattdm Oct 16 '18 at 15:23
  • @mattdm and that would be a system that isn't set up correctly for that sort of program. /var/tmp is for preserving data between reboots, not for large tmp files that you don't want to preserve. – UKMonkey Oct 17 '18 at 13:02