When an executable produces an output I prefer to let the executable print the output to stdout in order to redirect them in a file as well to pipe them to another command.

Let suppose that an executable has to write two distinct outputs, usually redirected to two distinct files. I would like to avoid passing the filenames to the executable and writing directly to files, instead I would like to write something like

$ program 1>file_1 3>file_2

Is possible to do something like that?

  • Why don't you just try before asking? – alex Jul 15 '11 at 12:34
  • I had no idea how to try... – mox Oct 23 '13 at 15:06

You can, but it's not a good idea. Normally programs start with three file descriptors open:

  • 0 is standard input, where commands that process text in some way read input if it's not coming from a file.
  • 1 is standard output, for normal data produced by a command if the data isn't explicitly going to a file.
  • 2 is standard error, for diagnostic messages that aren't part of the useful data produced by the command.

You can violate these conventions and use more file descriptors, but that means your application will only be directly usable in an environment where the caller has specified the right file descriptors. You won't easily be able to test for that in your application: since file descriptors 3 and above aren't regulated, they may be closed when your application starts (this can be detected), or they may be open for some unrelated purpose (this cannot be detected).

Passing file names on the command line is the normal way of specifying multiple input or output files.

That being said, to access arbitrary file descriptors:

  • In the shell: redirect to the desired number, e.g.

    IFS= read -r line <&3
    printf "%s\n" "$line" >&4
  • In C, call read or write with whatever fd you want, or call fdopen to get an stdio stream.
  • In Perl, specify a shell redirection as the file name to open to duplicate a file descriptor, or add = to do a plain fdopen.

    open IN3, "<&=3";
    open OUT4, ">&=4";
  • In Python, call os.fdopen.
| improve this answer | |

Yes, you certainly can. Note 1>file_1 can be simplified to >file_1 as 1 is the default.

For example:

$ cat test.ksh
echo "this goes to stdout" 
echo "this goes to stderr" >&2
echo "this goes to fd 3" >&3
$ ./test.ksh >file_1 3>file_2
this goes to stderr
$ cat file_1
this goes to stdout
$ cat file_2
this goes to fd 3
| improve this answer | |

You can redirect arbitrary file descriptors in the shell exactly as your example shows. Programs that work with multiple streams have to be told the names of files to use. If you really want to have the program use an fd you have redirected with the shell ( perhaps to a pipe ) then pass it /dev/fd/N for the file name to get it to use fd N.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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