How portable are /dev/stdin, /dev/stdout and /dev/stderr?

It's been available on Linux back into its prehistory. It is not POSIX, although many actual shells (including AT&T ksh and bash) will simulate it if it's not present in the OS; note that this simulation only works at the shell level (i.e. redirection or command line parameter, not as explicit argument to e.g. open()). That said, it should be available on most commercial Unix systems, one way or another (sometimes it's spelled /dev/fd/N for various integers N, but most systems with that will provide symlinks as Linux and *BSD do).


the /dev/std{in,out,err} files are normally just symlinks to /proc/self/fd/{0,1,2} (respectively). As such theres nothing gained over using methods that are POSIX defined.

If you want to be POSIX compliant, the best way to do this is to use output redirection. Shell output redirection is defined in the POSIX standard. Additionally the STDIN, STDOUT, STDERR file descriptor numbers are also part of POSIX.
In short, things like >&2 are guaranteed to work.

One important thing to note though is that usage of STDIN, STDOUT, and STDERR is subjective to how the program was started. If the program was started with file descriptor 1 being an open handle to a file, then your program just has to accept it. Even if you were to have the program open up /dev/stdout, all it would do is open up file descriptor 1 which is still going to point to that file.
If this is what youre trying to get around, you need to open the TTY directly. Normally, without any redirection going on, STDIN, STDOUT, and STDERR are all just open file descriptors pointing to the same TTY. There is absolutely nothing more to it than that.


POSIX 7 says they are extensions.

Base Definitions, Section 2.1.1 Requirements:

The system may provide non-standard extensions. These are features not required by POSIX.1-2008 and may include, but are not limited to:

[...]

  • Additional character special files with special properties (for example,  /dev/stdin, /dev/stdout,  and  /dev/stderr)

Found by grepping the POSIX HTML: Where is the list of the POSIX C API functions?

Also quite weirdly, the uuencode tool gives /dev/stdout a magic effect:

Specifying a decode_pathname operand of /dev/stdout shall indicate that uudecode is to use standard output.

The Linux kernel documentation says all systems should have it.

https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.rst

Compulsory links
These links should exist on all systems:
/dev/fd       /proc/self/fd   symbolic   File descriptors
/dev/stdin    fd/0            symbolic   stdin file descriptor
/dev/stdout   fd/1            symbolic   stdout file descriptor
/dev/stderr   fd/2            symbolic   stderr file descriptor

I could not, however, find where those symlinks are created in the kernel (distro provided?).