Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/scratch/edquist/git/bash/bash/inst/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I.. -I../include -I../lib -g -O2 uname output: Linux monza.cs.wisc.edu 2.6.32-573.7.1.el6.x86_64 #1 SMP Thu Sep 10 13:42:16 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu
Bash Version: 4.3 Patch Level: 46 Release Status: release Description: The docs say: Bash handles several filenames specially when they are used in redirections, as described in the following table: /dev/fd/[fd] If [fd] is a valid integer, file descriptor [fd] is duplicated. But in fact this is only true when HAVE_DEV_FD is undefined (see redir.c lines 522-524). Of course, when HAVE_DEV_FD is defined and the /dev/fd mechanism for opening files is available, the idea is _similar_ to fd duplication, but in fact there are important differences in the semantics: 1. if [fd] refers to a regular file, open(2)ing /dev/fd/[fd] via "command >/dev/fd/[fd]" will truncate the file, and "command >>/dev/fd/[fd]" will open it for append, but duplicating the file descriptor (eg, with "command >&[fd]") will neither truncate nor append, but will leave the file offset untouched. (And, moreover, the offset for the duplicated file descriptor will continue to be shared with [fd]'s after further updates.) 2. relatedly, (and not limited to regular files), it is possible to change the read/write mode of a file descriptor (O_WRONLY -> O_RDONLY) by re-open(2)ing /dev/fd/[fd], but this is not possible when duplicating fd. 3. regardless of file type, open(2)ing /dev/fd/[fd] requires appropriate permissions for open(2) to succeed, which is not required for duplicating a file descriptor. Repeat-By: Examples that demonstrate each of the above differences in semantics: (1) $ exec 5>foo $ echo hello >/dev/fd/5 $ echo goodbye >/dev/fd/5 $ cat foo goodbye $ versus: $ exec 6>bar $ echo hello >&6 $ echo goodbye >&6 $ cat bar hello goodbye $ (2) $ cat </dev/fd/6 hello goodbye versus: $ cat <&6 cat: -: Bad file descriptor (3) $ exec 7>baz $ chmod 400 baz $ echo ... >&7 versus: $ echo ... >/dev/fd/7 bash: /dev/fd/7: Permission denied Fix: Just fix the docs to clarify that /dev/fd/[fd] is only handled specially in redirections "on systems that do *not* support the /dev/fd method of naming open files" (to use the same language as the Process Substitution subsection in the docs). Fixing the docs here seems better than changing the code to match the docs, since (1) surely there are people that rely on the existing semantics (whether they realize it or not), despite it being contrary to the docs, and (2) sometimes (as in example 2 above) it is actually useful to open(2) /dev/fd/[fd] instead of duplicating it, and in any case if actual duplication is desired it can still be done with ">&[fd]" style redirections.