I've been trying to learn about file descriptors. When I type "ls -l /dev/fd/" I get

lrwx------ 1 me users 64 May  2 16:02 0 -> /dev/pts/5
l-wx------ 1 me users 64 May  2 16:02 1 -> /home/me/file
lrwx------ 1 me users 64 May  2 16:02 2 -> /dev/pts/5
lr-x------ 1 me users 64 May  2 16:02 3 -> /proc/31518/fd

/dev/fd/3 seems to be pointing to the current process. However, explanations of file descriptors I've seen, e.g. http://www.tldp.org/LDP/abs/html/io-redirection.html, don't say there's anything special about /dev/fd/3 (and imply it's just like any /dev/fd/N for N > 3). What's going on here?

I've observed this on arch linux and ubuntu, but not on the solaris server I have an ssh account on.


3 Answers 3


/dev/fd/3 seems to be pointing to the current process.

Ie., ls itself (notice that pid won't exist afterward). All of those actually pertain to the current process, as file descriptors are not global; there is not just a single 0, 1, and 2 for the whole system -- there's a separate 0, 1, and 2 for each process.

As Frederik Dweerdt notes, /dev/fd is a symlink. If you repeat your ls from different terminals, you'll notice links to different ptys. These will match the output of the tty command.

In the ls example, I would imagine descriptor 3 is the one being used to read the filesystem. Some C commands (eg, open()), which underpin the generation of file descriptors, guarantee the return of "the lowest numbered unused file descriptor" (POSIX -- note that low level open() is actually not part of Standard C). So they are recycled after being closed (if you open and close different files repeatedly, you will get 3 as an fd over and over again).

If you want a clue about how they come to exist, here's a snippet of C code using opendir(), which you'll probably find in the source for ls:

// open directory for reading
DIR *dh = opendir(".");
// print the fd of the directory handle to standard out:
printf("fd: %d\n", dirfd(dh));

Run as is, the fd will be 3, since that is the lowest unused descriptor (0, 1, and 2 already exist).


/dev/fd/3 is not a standard descriptor (edit: assignment). It (edit: having more than 0, 1 and 2) is specific to your case (ls). You can run ls through strace to understand what happens:

strace -e trace=openat,readlink ls -l /dev/fd/
readlink("/dev/fd/0", "/dev/pts/0", 65) = 10
readlink("/dev/fd/1", "/dev/pts/0", 65) = 10
readlink("/dev/fd/2", "/dev/pts/0", 65) = 10
readlink("/dev/fd/3", "/proc/28401/fd", 65) = 14

ls is to display the content of /dev/fd which is the same like /proc/self/fd. ls has to open the directory in order to read its entries. /dev/fd/3 is just the file descriptor to this directory.

Other programs don't have /dev/fd/3:

start cmd:> sleep 100 &
[1] 28414

ec:0   17:28:10  hl@inno:~/.wine/drive_c
start cmd:> ls -l /proc/28414/fd
insgesamt 0
crw------- 1 hl tty 136, 0 18. Apr 01:18 0
crw------- 1 hl tty 136, 0 18. Apr 01:18 1
crw------- 1 hl tty 136, 0 18. Apr 01:18 2
  • 1
    Maybe it is slightly misleading to say it is "not a standard descriptor. It is specific to your case..."? 3 is a normal file descriptor exactly like 0, 1, and 2, but 0, 1, and 2 have standard assignments (standard in, standard out, standard error) whereas 3 could be anything. Note it is possible to use 0, 1, and 2 in the same way, but this would be considered a bad practice.
    – goldilocks
    May 2, 2013 at 15:51
  • 1
    ^would be^ -> could be, since it's bound to happen if you, eg, close(0).
    – goldilocks
    May 2, 2013 at 17:08
  • If you already use fd 3, does ls choose a different fd? Feb 19, 2016 at 11:21
  • @CMCDragonkai Thy syscall open() uses the first free file descriptor. The calling application should not care about its number; that's why it is returned by the call. Feb 20, 2016 at 10:23

On Archlinux, /dev/fd is a symlink to /proc/self/fd. What you're seeing is the fd directory of your ls command. And this command indeed opened the directory as file descriptor 3.

EDIT: BTW, a good way to understand what's going on is to use strace. You'll see the process opening the file descriptors.

You must log in to answer this question.

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