11

When trying to redirect program output with the "some number greater than" syntax (eg foo 2> myfile), what are the possible numbers here and what do they represent?

I believe 1 is /dev/stdout, 2 is /dev/stderr. What about 5 & 6? Is there 3, 4 or some number greater than 6?

11

This supposed program will write to file descriptor number you specified. consider the following hello world program:

#include <stdio.h>

main()
{
   ssize_t i = 0 ;
   printf ("hello world\n") ;
   i = write( 5 , "Bonjour Monde\n", 14 ) ;
   printf ("%d octet dans 5\n", (int) i) ;
}

compile it

me@mybox:~/tmp7$ make hw
cc     hw.c   -o hw

now a simple run

me@mybox:~/tmp7$ ./hw
hello world
-1 octet dans 5

no file for 5, so no byte wrote.

next try:

me@mybox:~/tmp7$ ./hw 5> u
hello world
14 octet dans 5
me@mybox:~/tmp7$ cat u
Bonjour Monde

I manage to get an output while specifying a file and a file descriptor (e.g. 5>u ).

In practice, unless you have wrote such funny program as above, you are unlikely to collect data using 5>foo.

in shell script, construct using <( ) are more usefull:

 diff <( cmd -par 1 ) <(cmd -par 2)
  • write() returns ssize_t, not int. – Andrew Henle Oct 14 '15 at 9:38
  • That is not the main point of the question, there is also a return for the printf function. – Archemar Oct 14 '15 at 9:40
  • Not using a returned value is a whole lot different from using the wrong type. – Andrew Henle Oct 14 '15 at 9:43
  • edited I see no change in output tho ... – Archemar Oct 14 '15 at 10:03
10

The numbers represent file descriptors (handles to files that have been opened).

The shell usually has 3 set automatically,

0 - stdin 1 - stdout 2 - stderr

But further files can be opened, and the numbers increment.

7

Those numbers are file descriptors. As you noted, there are several that are created automatically. As other files or file-like things are opened, they will get other numbers.

The numbers that are used in any particular program are dependent on what files have been opened by that program, or otherwise used. For example, if you want to "save" the current stdin and temporarily redirect stdin from elsewhere then restore it later, you could do something like:

exec 4<&0
exec < /some/file
#process
exec 0<&4 4<&- # restore stdin and close our duplicate

So this script would have a 4 file descriptor available at least for some time. That 4 could be anything that's not in use though (well, there is a limit for how many files a process can have open, but anything within that limit).

You can see what file descriptors a process has open, and where they are open to by looking in /proc/<pid>/fd. That shows all the open file descriptors for that process <pid> and what files those are associated with.

0

Any process get integer numbers as file descriptors, where there are three reserved ones in POSIX: 0 is stdin, 1 is stdout and 2 is stderr. Any further files will be assigned further numbers. You can check it easily with this program, save it as fdtest.c, so that it open its own program code during runtime:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
    int fd = open("fdtest.c", O_RDONLY);
    printf("%d\n", fd);
    close(fd);
    return 0;
}

Compile it:

gcc fdtest.c -o fdtest

Run it:

./fdtest

Output you will get is something like this:

3

... which is the number of the file descriptor of the file referred to by the variable fd.

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.