The XDG Base Directory Specification is a very interesting spec for user directories. It also provides good default values, except for XDG_RUNTIME_DIR.

Now I am writing a software that needs to create named pipes. It is a per-user client-server framework (there is a FIFO for the server and a FIFO per client).

If XDG_RUNTIME_DIR is not defined, I am currently using a per-user subdirectory in /tmp — but it does not ensure all the specified conditions (viz. the paragraph starting with "The lifetime of the directory MUST be bound to the user being logged in…")

Is /tmp/myserver-$USER good enough?


I saw elsewhere a few suggestions:

  • . is quite unsatisfactory (at least because it is not an absolute path).
  • I also saw /var/run/user/$USER — not bad, but that directory does not exist (at least on my box running a Debian testing)

3 Answers 3


/tmp is used by plenty of programs in a similar way already. On my system I can see the /tmp/orbit-$USER (used by Gnome's ORBit2) and /tmp/.X11-unix/ (Xorg and X11) directories with plenty of pipes, ehm, sockets, in them. I am sure there are also others, so I see nothing wrong with what you are doing. Just be prepared that since it is a world writeable location a malicious process can hijack the location (verify the permissions before you write to it).

I can also recommend $TMPDIR for those who use pam_mktemp, as this directory is only accessible by the user.

  • PAM is the right solution, thanks! On Debian it is called libpam-tmpdir
    – cadrian
    Commented Jun 3, 2012 at 7:23

SystemD makes /run/user/$UID kinda mandatory.


Unprivileged Write Access

Unprivileged processes generally lack write access to most of the hierarchy.

The exceptions for normal users are /tmp, /var/tmp, /dev/shm, as well as the home directory $HOME (usually found below /home) and the runtime directory $XDG_RUNTIME_DIR (found below /run/user) of the user, which are all writable.

For unprivileged system processes only /tmp, /var/tmp and /dev/shm are writable. If an unprivileged system process needs a private, writable directory in /var or /run, it is recommended to either create it before dropping privileges in the daemon code, to create it via tmpfiles.d(5) fragments during boot, or via the RuntimeDirectory= directive of service units (see systemd.unit(5) for details).


If it does not exist yet, the user runtime directory /run/user/$UID is either created or mounted as new "tmpfs" file system with quota applied, and its ownership changed to the user that is logging in.

  • /run/user/${USER} on my machine means /run/user/mazunki, while systemd uses /run/user/1000 on all the machines I've seen, and I am pretty sure this is the norm. There is /run/user/${UID}, or the better /run/user/$(id -u). Or am I misunderstanding something?
    – mazunki
    Commented Jul 20, 2022 at 19:17
  • Thanks for the correction @mazunki
    – go2null
    Commented Dec 15, 2022 at 14:47

Create directory /tmp/service-$USER.id with unique id. For exsmple, in shell:

mktemp -d /tmp/service-"$USER".XXX
  • 1
    How do you ensure the requirement that the same directory is used from the first login to the last logout of the user?
    – cadrian
    Commented Jun 1, 2012 at 13:10
  • Hmmm... create symlink ~user/.service/tmp_dir. If linked directory does not exist, create new Commented Jun 2, 2012 at 1:05
  • export XDG_RUNTIME_DIR=$(ls -d /tmp/service-$USER.???* 2>/dev/null || mktemp -d /tmp/service-$USER.XXX | tee >(xargs chmod 0700))
    – Ryan Lue
    Commented Jul 12, 2022 at 1:51
  • @RyanLue Cool stuff, using $TMPDIR instead of /tmp seems to make commands compatible with macOS. Problem is just, this will not remove the directory when all sessions are terminated, thus it doesn't follow the implementation fully as necessary. Commented Dec 29, 2022 at 17:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .