100

When configuring an application, you can often use /dev/null as config file if you want the application to read an empty file. But, if the application reads a list of files from a directory, you cannot use this trick. You would need to give it an empty directory to read.

I was wondering: does Linux have a default empty directory that can be used for such purposes? I know OpenSSH used /var/empty for a while, and I can of course create an empty dir myself, but maybe the FHS has specified a standard directory for this?

roelvanmeer
  • 1,764
  • 3
  • 13
  • 27
  • 8
    On my system, `/var/empty` is not empty, but contains a folder called `sshd`, so you probably don't want to use that. – knub Dec 07 '16 at 11:30
  • If it's just for you you could always create `/var/empty` – user253751 Dec 07 '16 at 20:47
  • 14
    Just a point: The special aspect of `/dev/null` isn't so much for *reading* as for *writing.* Data written to `/dev/null` just disappears. So, a directory equivalent would be a place where `mv yourfile /dev/empty` would result in deleting your file. – Wildcard Dec 07 '16 at 21:03
  • 4
    @Wildcard I presume you mean `mv yourfile /dev/empty/`. If you do `mv yourfile /dev/empty`, you're trying to replace the special directory. – Rhymoid Dec 07 '16 at 22:24
  • 1
    @Wildcard The obvious caveat here is that when crossing file system boundaries `mv` will copy all the files first and then delete the originals. So that could turn into a very inefficient way to delete files. – kasperd Dec 07 '16 at 23:48
  • @Wildcard while you're generally correct, it's worth noting (to avoid misconceptions) that piping `/dev/null` through `dd` is often used to initialize swapfiles. – Jules Dec 08 '16 at 16:42
  • 1
    @Rhymoid if a directory already exists, `mv` interprets a command such as `mv file /path/to/directory` as "move the file into the directory". – micheal65536 Dec 08 '16 at 17:15
  • 6
    @Jules No, it isn't. You can't initialise anything with `/dev/null` and `dd` because `dd` will get an EOF before it's even written a single byte. I think you're thinking of `/dev/zero`, which is often used to fill something with or generate a specific number of zeros. – micheal65536 Dec 08 '16 at 17:16
  • @MichealJohnson Good point. It kinda depends on how `mv` detects that, and whether it will know that a special directory is "special" or not. – Rhymoid Dec 08 '16 at 17:42
  • 2
    @MichealJohnson you're right, my mistake, I'd confused `/dev/null` with `/dev/zero`. – Jules Dec 08 '16 at 17:52
  • @MichealJohnson If you need a file of a certain size you can create it using for example `dd if=/dev/null of=target seek=100 bs=1G` if the needed size is 100GB. It won't work for swap files though because the created file will be sparse and a swap file must not be sparse. – kasperd Dec 09 '16 at 21:36
  • @Wildcard: (1) It’s important that `/dev/null` return an immediate EOF on input, because asynchronous (background) processes have their stdin redirected to `/dev/null`. This is better than just closing stdin (as in `<&-`) because (1a) that would cause `read()` to return an error rather than EOF, and (1b) it would allow the next `open()` to return 0. (2) `grep` didn’t always have the `-H` (`--with-filename`) option. Before that existed, `grep pattern /dev/null *` was the standard trick to get `grep` to report the filename even if `*` expanded to only one file. – Scott - Слава Україні Dec 12 '16 at 06:35
  • @kasperd - won't running `mkswap` on the 100G file finish making it swap? – warren Dec 12 '16 at 18:07
  • @warren All that `mkswap` does is to write a header to the file. It will still be sparse. Test this sequence of commands `dd if=/dev/null of=target seek=100 bs=1G`; `mkswap target`; `swapon target`. (You don't even need to be `root` to test that as it fails before you even reach the step that checks for root privileges.) – kasperd Dec 12 '16 at 21:30
  • pathconf: not a directory. – neverMind9 Dec 01 '18 at 02:58

4 Answers4

73

The FHS provides no "standard" empty directory.

It is common for Linux systems to provide a directory /var/empty, but this directory is not defined in FHS and may not actually be empty. Instead, certain daemons will create their own empty directories in here. For instance, openssh uses the empty directory /var/empty/sshd for privilege separation.

If your need for an empty directory is transient, you can create an empty directory yourself, as a subdirectory of /run or /tmp. If you're doing this outside the program, you can use mktemp -d for this, or use the mkdtemp(3) C function inside your program. Though if you always need the empty directory to be present, consider creating one under /var/empty as openssh does.

For this use case, creating a directory under /tmp is probably the best fit, though in practice it doesn't matter very much where you put it.

Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
  • 5
    I would not recommend creating subdirectories under `/var/empty`, since any programs that use it (like OpenSSH in its [default config](https://github.com/openssh/openssh-portable/blob/fdfbf4580de09d84a974211715e14f88a5704b8e/pathnames.h#L157)) may expect it to be actually empty. (The `/var/empty/sshd` thing appears to be a weird RedHat-ism; Debian uses `/var/run/sshd` instead.) – Ilmari Karonen Dec 08 '16 at 12:35
  • 3
    @IlmariKaronen The bit of code you've linked doesn't support your assertion that OpenSSH expects `/var/empty` to be empty. Is there somewhere else one might look for this? – Michael Hampton Dec 08 '16 at 15:56
  • https://github.com/openssh/openssh-portable/blob/master/README.privsep maybe? – Ilmari Karonen Dec 08 '16 at 17:56
  • 2
    @IlmariKaronen Hm, that document is out of date. It refers to `/var/empty` but the code actually uses `/var/empty/sshd`. Try again. :) – Michael Hampton Dec 08 '16 at 17:58
  • The link I gave points to the head of the `master` branch of the portable OpenSSH project on Github. It *should* be up to date; can *you* substantiate your claim that "the code actually uses `/var/empty/sshd`"? As far as I can tell, it does not, unless the default `/var/empty` path is altered by you or your distro (as RedHat, apparently, does). If it did, I'd expect the path `/var/empty/sshd` to actually be [mentioned outside the `contrib/redhat` folder](https://github.com/openssh/openssh-portable/search?q=%22%2Fvar%2Fempty%2Fsshd%22&type=Code) in the code. – Ilmari Karonen Dec 09 '16 at 16:08
  • 1
    @IlmariKaronen Hmm. Now I think you're right, after actually looking at the source which does the chroot() call. I find it amazing that there would be such an obviously stupid flaw in openssh, that Red Hat would have to maintain a downstream correction for. – Michael Hampton Dec 09 '16 at 16:16
  • 3
    I don't see how it's a "stupid flaw" -- having a guaranteed empty root-owned directory at a standard location, for use as a chroot jail, seems like a perfectly good idea to me. Of course, RedHat had to go and ruin it for everybody, by creating subdirectories under it. As a result, my recommendation for portable code would be not to use `/var/empty` for anything, since you can't be sure of its semantics on any given system. Creating your own empty directory e.g. under `/var/run`, like Debian does, seems more sensible. – Ilmari Karonen Dec 09 '16 at 16:43
  • @IlmariKaronen No, it's a terrible idea, especially for this purpose. You don't want multiple daemons chrooting to the same directory. They could then leak information among each other. Having a unique empty directory for every daemon closes this hole. – Michael Hampton Dec 09 '16 at 16:45
  • 2
    Not if it's owned by root and not writable, like `/var/empty` on *BSD is. – Ilmari Karonen Dec 09 '16 at 16:46
37

You can use mktemp -d to create a new empty temporary directory with secure permissions, by default in /tmp/. The utility will output the new directory's path on STDOUT, so it is useful in the shell.

It's more portable than a systemd unit file anyway.

oals
  • 471
  • 3
  • 5
  • Yes, you could, but that's impractical if that directory has to be specified in a configuration file. You would want a permanent dir for that. – roelvanmeer Dec 08 '16 at 20:12
32

This Unix question has some suggestions for creating a "blackhole" directory, including a nullfs FUSE filesystem.

200_success
  • 4,771
  • 1
  • 25
  • 42
  • 3
    I do not know why the mktemp / mkdtemp answer is upvoted so heavily when this is the perfect answer. nullfs is the equivalent of /dev/null. – chx Dec 10 '16 at 05:49
12

For services systemd provides the option PrivateTmp to create private /tmp and /var/tmp directories that are not shared by processes outside of the namespace for that service and which should be empty (initially).

[Service]
ExecStart=...
PrivateTmp=yes 
HBruijn
  • 77,029
  • 24
  • 135
  • 201
  • 7
    The program might create other temporary files, so you can't assume `/tmp` will be empty merely because it's been namespaced. – Michael Hampton Dec 07 '16 at 16:18