Linux Files – Why Can’t /dev/stdout Be Read with Text Editor?

fileslinuxstdout

I just started learning how Everything Is A FileTM on Linux, which made me wonder what would happen if I literally read from /dev/stdout:

$ cat /dev/stdout 
^C
$ tail /dev/stdout 
^C

(The ^C is me killing the program after it hangs).

When I try with vim, I get the unthinkable message: "/dev/stdout" is not a file. Gasp!

So what gives, why am I getting hangups or error messages when I try to read these "files"?

Best Answer

why am I getting hangups

You aren't getting "hangups" from cat(1) and tail(1), they're just blocking on read. cat(1) waits for input, and prints it as soon as it sees a complete line:

$ cat /dev/stdout
foo
foo
bar
bar

Here I typed fooEnterbarEnterCTRL-D.

tail(1) waits for input, and prints it only when it can detect EOF:

$ tail /dev/stdout
foo
bar
foo
bar

Here I typed again fooEnterbarEnterCTRL-D.

or error messages

Vim is the only one that gives you an error. It does that because it runs stat(2) against /dev/stdout, and it finds it doesn't have the S_IFREG bit set.

/dev/stdout is a file, but not a regular file. In fact, there's some dance in the kernel to give it an entry in the filesystem. On Linux:

$ ls -l /dev/stdout
lrwxrwxrwx 1 root root 15 May  8 19:42 /dev/stdout -> /proc/self/fd/1

On OpenBSD:

$ ls -l /dev/stdout
crw-rw-rw-  1 root  wheel   22,   1 May  7 09:05:03 2015 /dev/stdout

On FreeBSD:

$ ls -l /dev/stdout
lrwxr-xr-x  1 root  wheel  4 May  8 21:35 /dev/stdout -> fd/1

$ ls -l /dev/fd/1
crw-rw-rw-  1 root  wheel  0x18 May  8 21:35 /dev/fd/1
Related Question