For more info visitTo understand File Descriptor manipulation we will have to know, what are file descriptors?
Whenever we run a process, Unix automatically associates some indicators with the process for accessing input and output devices. The default indicators which unix associates with any process are
0 - Input from user or standard input.
1- Output to user or standard output.
2- Error output which shares the same stream as standard output i.e , standard output and error output share the terminal.
When we login into the terminal , unix kernel creates a shell for us which is a process. 0,1,2 are also associated with the shell.We can also redirect these file descriptors to some other source for example
echo John > myfile
It actually means
cat John 1> myfile
This simply means, redirect the output, which was actually meant for standard output, to the file "myfile". Now the output will go to the file "myfile", instead of coming on screen. We all know that in unix, everything is treated as a file. Standard input/output terminal is not an exception to this, /dev/tty is the file associated with every terminal which is connected to Unix system. Remember, there can be one or more terminal connected to a Unix system with different user working on each system. So whenever anyone tries to use /dev/tty, it corresponds to their own terminal.
I already told you that error stream also shares the same output device as output stream, i.e terminal .We can also redirect error stream to some file, instead of showing it on terminal.
cat zombie 2>myfile
I don't have any file "zombie" in my system, but instead of showing error on terminal , I am redirecting error to the file "myfile".
We can also manipulate file descriptors using exec command. For example, if we run the following command on the shell.
exec 1>myfile
Now, whenever we try to print something on terminal, it will go to the file. This is because we have redirected output stream of the process "shell" to myfile. We won't be able to see the contents of myfile, since it is being used by the process "shell" to store its output. We can see the contents of "myfile" once we redirect the shell's output stream back to "/dev/tty", using
exec 1>/dev/tty.
We can also create our own file descriptors and associate them with some file. Those file descriptors can have numbers like 3,4,5..... .Whenever we create our own file descriptor the shell opens file, either in reading or writing mode depending on the file descriptor made. This happens in the background, and user never gets to know about this. So, creation of every file descriptor leads to opening of a file, or more precisely opening of any file by a process leads to creation of a file descriptor. Generally, kernel maintains these file descriptors to keep track of access patterns for a file. For example.
exec 3>myfile
Output file desciptor 3 is associated with "myfile". We can write commands like the following to send output to "myfile".
echo hello >&3
Above command will put output "
hello" in "
myfile" instead of displaying it on screen.
We can also create an input file descriptor for a file.
exec 4<myfile
After this, the process can take input from this file.
cat <&4
We can also create a file descriptor based on some other file descriptor. For example, 4 is the input file descriptor for "myfile".We can associate some other input file descriptor, using file descriptor 4, with "
myfile".
exec 5<&4
Now, we can read input from
myfile using any file descriptor(4 or 5). In the same way we can do it for output file descriptor.
Note:
i) Whenever we create a file desciptor using another descriptor then both should be either output file descriptor or input file descriptor.
ii) Whenever we close one file descriptor for a file, then it doesn't close other file descriptor which was made using the previous file descriptor. In the example if we close file descriptor 5, it won't close file descriptor 4.
iii) A file descriptor made with the help of other file descriptor shares the same pointer to the file in the file table.
Closing of File Descriptor
We can close the file descriptor using following command.
exec 4>&-
Note: We always close the file descriptor using ">", irrespective of the fact that it's an input file descriptor or an output file descriptor.