mkfifo makes a named pipe: a file-shaped rendezvous point where a writer and a reader meet, and neither one gets anywhere until the other turns up. You will create a FIFO, connect a writer to a reader through it, check its type and permissions, then remove it cleanly. Allow about ten minutes. The examples use GNU coreutils 9.4, installed here as Debian package coreutils 9.4-3ubuntu6.3. You need a shell and write permission in the directory where the FIFO will live.
A FIFO does not store a normal file's contents. It is a rendezvous point, not a queue: a command that opens it can end up waiting until the other side is present.
Confirm the executable and version before relying on details in a script. These are ordinary read-only commands and do not need elevated privileges:
$ command -v mkfifo
/usr/bin/mkfifo
$ mkfifo --version
mkfifo (GNU coreutils) 9.4
$ dpkg-query -W -f='${Package} ${Version}\n' coreutils
coreutils 9.4-3ubuntu6.3
The installed manual documents the basic form as mkfifo [OPTION]... NAME.... It accepts one or more names and creates a FIFO at each one. It does not start a reader or writer for you: that part is on you.
Use a directory that is yours to modify. A temporary directory keeps the named pipe away from application and service paths:
$ workdir=$(mktemp -d)
$ mkfifo "$workdir/events"
$ stat -c '%F %a %n' "$workdir/events"
fifo 644 /tmp/tmp.XXXXXXXXXX/events
The random directory suffix will differ on your machine. The first field must say fifo. With the shell's usual umask 022, the default permission bits are commonly 644: mkfifo starts from read and write for everyone, then the umask trims it. Those permissions control who may open the FIFO; they do not turn it into a persistent queue.
Checkpoint: if mkfifo reports that the file exists, do not overwrite it blindly. Inspect it first:
$ stat "$workdir/events"
$ test -p "$workdir/events" && echo 'named pipe confirmed'
named pipe confirmed
Use -m or --mode when the default permissions are not suitable. The mode is interpreted as permission bits and is not then trimmed by the umask the way the default is:
$ mkfifo --mode=0600 "$workdir/private-events"
$ stat -c '%F %a %n' "$workdir/private-events"
fifo 600 /tmp/tmp.XXXXXXXXXX/private-events
No sudo is needed when the directory belongs to you. Elevated privileges only address filesystem permissions; they do not make a blocked reader or writer safe, and using root can leave a root-owned entry that your normal account cannot remove.
Opening a FIFO for writing can wait until a reader opens it. Start the writer in the background, then read from the FIFO in the foreground:
$ printf 'event: ready\n' > "$workdir/events" &
$ writer_pid=$!
$ cat "$workdir/events"
event: ready
$ wait "$writer_pid"
$ printf 'writer exit status: %s\n' "$?"
writer exit status: 0
The background job supplies one line and exits once the reader consumes it. cat reaches end of input when the writer closes its descriptor. The FIFO itself stays in the directory after the data has been read; it is not a file you can reopen to get the same line back.
Checkpoint: if the terminal appears to hang, the shell is probably waiting for the other endpoint. Press Ctrl-C to stop a foreground test, then inspect jobs with jobs -l. A background writer can stay blocked until a reader arrives, so run wait before starting another test and avoid leaving stray jobs behind.
Before creating a name, check whether it already exists. This stops you swapping an application's endpoint for a different kind of object by accident:
$ if test -e "$workdir/events"; then
> test -p "$workdir/events" || { printf 'not a FIFO\n' >&2; exit 1; }
> else
> mkfifo "$workdir/events"
> fi
$ test -p "$workdir/events" && echo 'safe FIFO endpoint'
safe FIFO endpoint
Warning: do not use rm or recreate the path while another service may be using it. Removing a FIFO unlinks its name but does not stop processes that already have it open. Coordinate with the service owner before changing a shared endpoint.
Removal is destructive to the named endpoint, although it does not erase data from a regular file, because the FIFO never stored any. Stop any test jobs first, then remove only the paths you created:
$ jobs -l
$ rmdir "$workdir" 2>/dev/null || true
$ rm -f "$workdir/events" "$workdir/private-events"
$ rmdir "$workdir"
$ test ! -e "$workdir" && echo 'scratch FIFO directory removed'
scratch FIFO directory removed
The first rmdir normally fails because the FIFO files still exist, so its output is suppressed and the cleanup carries on. If the path contains anything you did not create, stop and inspect it rather than widening the removal command. Cleaning a shared FIFO instead: use the owning application's documented shutdown procedure first.
stat and test -p. The existing path may be a regular file, socket, directory or another FIFO.sudo.mkfifo --version reports the expected installed coreutils version.test -p NAME confirms that the endpoint is a FIFO.