7

From the The GNU Bash Reference Manual, section 3.6 Redirections:

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.

/dev/stdin

    File descriptor 0 is duplicated.

/dev/stdout

    File descriptor 1 is duplicated.

/dev/stderr

    File descriptor 2 is duplicated.

what does "duplicated" mean here? Can you give some examples?

(The above excerpt is from Edition 4.3, last updated 2 February 2014, of The GNU Bash Reference Manual, for Bash, Version 4.3.)

2 Answers 2

14

Redirections are implemented via the dup family of system functions. dup is short for duplication and when you do e.g.:

3>&2

you duplicate (dup2 ) filedescritor 2 onto filedescriptor 3, possibly closing filedescriptor 3 (dup2(2,3)) if it's already open (which won't do a thing to your parent process, because this happens in a forked off child (if it does not (redirections on shell functions in certain contexts), the shell will make it look as if it did)).

When you do:

1<someFile

it'll open someFile on a new file descriptor (that's what the open syscall normally does) and then it'll dup2 that filedescriptor onto 1 (dup2(newfd,1)).

The target filedescriptor of the duplication is always ampersand-less on the left-hand side (might be helpful to think of redirections as left=right assignments without getting confused by the confusing directionality of </>>/>), and the right hand side has the filename to open the source file from (>, >>, or < then determine how it should be open -- for writing with truncation and possible creation, for appending and possible creation or for reading only), or, the right hand side has an ampersand followed by the source filedescriptor (which is unaffected by >, >>, or <). If the left-hand side is omitted, 1 is implied for > or >> and 0 for <.

What the manual says is that if one of the special dev files listed takes the place of someFile, the shell will skip the open-on-a-new-fd step and instead go directly to dup2ing the matching filedescriptor (i.e., 1 for /dev/stdout, etc.) onto the target (filedescriptor on the left side of the redirection), so

  • /dev/stdin as the redirection source (RHS) <=> &0
  • /dev/stdout as the redirection source (RHS) <=> &1
  • /dev/stderr as the redirection source (RHS) <=> &2
  • /dev/fd/$somefd as the redirection source (RHS) <=> &$somefd
2
  • @BoreaDeitz Thanks for the feedback. Added some more text to hopefully clarify it better. The redirection syntax might be confusing because >, >>, < confusingly seem to imply directionality, but redirections are more like normal right-to-left assignments of a duplicate, where the right side either has &filedescriptor and choosing between >, >>,< has no effect, or it has a filename and then the arrows determine how it should be open before the resultant fd is moved to the target (dup2(newfd,dest) + maybe close(newfd) unless it was already opened at the target). Commented May 19, 2023 at 19:34
  • Your reaction is amazingly fast :). I was in the middle of drafting that comment when it posted itself while i was on another tab doing more reading. I'm going to delete it, since I never meant to post it and it's incomplete, but I'm leaving this note so other readers know what happened. Commented May 19, 2023 at 19:54
0

A file descriptor is a pointer to a kernel's global file table (see https://www.computerhope.com/jargon/f/file-descriptor.htm e.g.). So it has it's number (acting as it's label or name) and value (an actual pointer). When you duplicate file descriptors one onto another, you actually copy a pointer value from the source filedes to the target filedes, thus duplicating the source into the target.

So the statement:

Bash handles several filenames specially when they are used in >redirections, as described in the following table. [...]

/dev/stout

  File descriptor 1 is duplicated

means, that when you do "n >/dev/stdout " (redirect to /dev/stdout or duplicate /dev/stdout fd into n fd), bash simly duplicates the fd "1" instead. If you would redirect to a regular (non special file), bash would create new file descriptor and duplicate it to the file descriptor which you are redirecting.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .