Monday, October 20, 2008

bash: file descriptors

In bash you may open file descriptor for reading or(and) writing.
To create file descriptor for reading, writing, reading and writing use these commands:

[fd]<[source] #read-only
[fd]>[source] #write-only
[fd]<>[source] #read-write
[fd] is a digit that describes file descriptor and [source] can be either another file descriptor(should be with leading &) or any other source for reading or writing.
If the source is other file descriptor the new one will be a duplicate.
#file descriptor 3 is opened for reading
#and already contains '123' which comes from the 'echo' command
3< <(echo 1 2 3)
#file descriptor 3 is opened for writing
#which output will be printed to stdout by 'cat' tool
3> >(cat)
#file descriptor 3 is opened for reading/writing
#from/to test.file file
3<>test.file
To move descriptor add '-' suffix to the [source] descriptor.
3<&2- #stderr is redirected to descriptor 3 and closed
By executing
ls -l /proc/$$/fd
you can see what file descriptors are opened for current process.
Using exec for creating/redirecting/duplicating file descriptors allows the changes to take effect in the current shell. Otherwise they are local to subroutine.
#file descriptor 3 is local for 'while' loop
#you can't use it outside
while read line <&3; do echo $line; done 3<test.file
#file descriptor 3 is visible within current process
exec 3<test.file
while read line <&3; do echo $line; done
Special cases of redirection to stdin of the program are 'Here Documents' and 'Here Strings'.
#the shell reads input from the current source until
#a line containing only [word] (with no trailing blanks) is seen
<<[word]
#the shell reads input from the current source until
#a line containing only [word] (with no trailing blanks) is seen
#but all leading tab characters are stripped from input lines and the line containing [word]
<<-[word]
#[word] is expanded and supplied to the command on its standard input
<<<[word]
The examples
$exec 3<<EOF
> text is here
> EOF
$cat <&3
text is here

$exec 3<<<string
$cat <&3
string

No comments: