Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Occasionally I need to specify a "path-equivalent" of one of the standard IO streams (stdin, stdout, stderr). Since 99% of the time I work with Linux, I just prepend /dev/ to get /dev/stdin, etc., and this "seems to do the right thing". But, for one thing, I've always been uneasy about such a rationale (because, of course, "it seems to work" until it doesn't). Furthermore, I have no good sense for how portable this maneuver is.

So I have a few questions:

  1. In the context of Linux, is it safe (yes/no) to equate stdin, stdout, and stderr with /dev/stdin, /dev/stdout, and /dev/stderr?

  2. More generally, is this equivalence "adequately portable"?

(I cringed as I wrote the last question, because I wish I could make it less subjective...)

I tried Googling these questions, including terms like POSIX among my search terms, but none of the top hits I got were particularly germane or authoritative.

share|improve this question
    
up vote 19 down vote accepted

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).

share|improve this answer
7  
Indeed, /dev/std{in,out,err} are specifically listed as not part of the POSIX.1-2008 standard. – jw013 Apr 13 '12 at 23:05
    
It appears that ash doesn't support /dev/stdout in initrd (git.razvi.ro/…) – CMCDragonkai Feb 13 at 5:48

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.

share|improve this answer
1  
+1, especially for the "one important thing" part; I'm going to digest this in parts :) – Alois Mahdal Apr 15 '12 at 13:22
1  
Can you clarify if /proc/self/fd/1 or /dev/fd/1 are part of POSIX? – Steven Penny Jun 15 '14 at 2:32

It should be available on all Linuxes. Linux 4.1 Documentation/devices.txt says:

    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
/dev/nfsd   socksys     symbolic    Required by iBCS-2
/dev/X0R    null        symbolic    Required by iBCS-2

I could not however find where those symlinks are created on the kernel.

I could not however find it mentioned even on the LSB.

share|improve this answer

One issue with /dev/stdout and friends is that you may not have permission to write to them in certain circumstances. For example, I've encountered this when invoking scripts from Nix, and I imagine similar tools which run scripts in jails/sandboxes/containers/VMs/etc. may encounter similar issues.

Using syntax like 1>&2 worked in these cases and, since I knew I'd be running in Bash, I could use process substitution for commands which expect filenames.

share|improve this answer

/dev/{stdout,stdin,stderr} work in Bash on these platforms:

Linux debian-ppc 3.16.0-4-powerpc #1 Debian 3.16.7-ckt25-1 (2016-03-06) ppc GNU/Linux
HP-UX hpux-ia6 B.11.31 U ia64 0107668277 unlimited-user license
AIX aix7 1 7 000ACFDE4C00
FreeBSD freebsd.polarhome.com 10.0-RELEASE-p7 FreeBSD 10.0-RELEASE-p7 #0: Tue Jul  8 06:37:44 UTC 2014     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  amd64
HP-UX hpux64 B.11.11 U 9000/785 2000587908 unlimited-user license
Darwin macosx 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:26:45 PDT 2012; root:xnu-1699.32.7~1/RELEASE_I386 i386
GNU hurd 0.7 GNU-Mach 1.6-486/Hurd-0.7 i686-AT386 GNU
Linux mandriva.polarhome.com 2.6.33.7-desktop-2mnb #1 SMP Mon Sep 20 18:19:20 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
SunOS openindiana 5.11 oi_148 i86pc i386 i86pc
MirBSD miros.polarhome.com 10 Kv#10uAF-20110818 GENERIC#1330 i386
Linux pidora 3.12.23-2.20140626git25673c3.rpfr20.armv6hl.bcm2708 #1 PREEMPT Fri Jul 4 16:06:10 EDT 2014 armv6l armv6l armv6l GNU/Linux
QNX qnx 6.5.0 2010/07/09-14:44:03EDT x86pc x86
NetBSD netbsd.polarhome.com 6.1.3 NetBSD 6.1.3 (GENERIC) i386
OpenBSD openbsd.polarhome.com 4.9 GENERIC#671 i386
Linux raspbian 3.18.7+ #755 PREEMPT Thu Feb 12 17:14:31 GMT 2015 armv6l GNU/Linux
SCO_SV scosysv 5 6.0.0 i386
Linux redhat.polarhome.com 3.17.4-301.fc21.x86_64 #1 SMP Thu Nov 27 19:09:10 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
SunOS solaris-x86 5.11 11.3 i86pc i386 i86pc
Linux suse 3.4.63-2.44-desktop #1 SMP PREEMPT Wed Oct 2 11:18:32 UTC 2013 (d91a619) x86_64 x86_64 x86_64 GNU/Linux
SunOS solaris 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-V210
Linux ubuntu 3.13.0-85-generic #129-Ubuntu SMP Thu Mar 17 20:50:15 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
UnixWare unixware 5 7.1.4 i386 x86at SCO UNIX_SVR5
OSF1 tru64.polarhome.com V5.1 2650 alpha
Linux debian 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u2 (2016-01-02) x86_64 GNU/Linux

But fails in csh on these:

HP-UX hpux-ia6 B.11.31 U ia64 0107668277 unlimited-user license
Linux centos.polarhome.com 2.6.18-409.el5 #1 SMP Tue Mar 15 18:13:50 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux
HP-UX hpux64 B.11.11 U 9000/785 2000587908 unlimited-user license
AIX aix7 1 7 000ACFDE4C00
SCO_SV scosysv 5 6.0.0 i386
SunOS solaris-x86 5.11 11.3 i86pc i386 i86pc
SunOS openindiana 5.11 oi_148 i86pc i386 i86pc
SunOS solaris 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-V210
UnixWare unixware 5 7.1.4 i386 x86at SCO UNIX_SVR5
OSF1 tru64.polarhome.com V5.1 2650 alpha
share|improve this answer
    
What was your test case? bash is special as it can be compiled to handle /dev/fd/x by itself for redirections on systems that don't have /dev/fd – Stéphane Chazelas Apr 22 at 16:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.