Every process has three standard files open upon creation. These are called standard input, standard output, and standard error, and are given file descriptors 0, 1, and 2, respectively. These are commonly known as stdin, stdout, and stderr. ls -l /proc/self/fd shows the files open by the ls command itself; after these standard 0, 1, and 2, ls has also opened the directory /proc/5820/fd to list it (5820 being the PID of ls itself), with a file descriptor of 3.
$ ls -l /proc/self/fd total 0 lrwx------ 1 steve steve 64 Jan 27 21:34 0 -> /dev/pts/1 lrwx------ 1 steve steve 64 Jan 27 21:34 1 -> /dev/pts/1 lrwx------ 1 steve steve 64 Jan 27 21:34 2 -> /dev/pts/1 lr-x------ 1 steve steve 64 Jan 27 21:34 3 -> /proc/5820/fd $
Because everything is a file, even the concepts of input and output are also files. Here, the controlling terminal (/dev/pts/1) is the source of input, and also where output and errors must be redirected. ls does not really take interactive input, but its output, and any errors it has to report, go to the controlling terminal so that when users run the ls command, they see its output on their terminal.
Because these are files, they can be redirected to other files. The > operator is used to redirect output from one file to another. Running the ls command again, but directing its output to /tmp/ls-output.txt shows nothing on the terminal because all output has gone to the file in /tmp instead.
$ ls -l /proc/self/fd > /tmp/ls-output.txt $