Linux Shell Scripting Tutorial (LSST) v1.05r3
Prev
Chapter 4: Advanced Shell Scripting Commands
Next

I/O Redirection and file descriptors

As you know I/O redirectors are used to send output of command to file or to read input from file. Consider following example
$ cat > myf
This is my file
^D
(press CTRL + D to save file)
Above command send output of cat command to myf file

$ cal
Above command prints calendar on screen, but if you wish to store this calendar to file then give command
$ cal > mycal
The cal command send output to mycal file. This is called output redirection.
$ sort
10
-20
11
2

^D
-20
2
10
11
sort command takes input from keyboard and then sorts the number and prints (send) output to screen itself. If you wish to take input from file (for sort command) give command as follows:
$ cat > nos
10
-20
11
2

^D
$ sort < nos
-20
2
10
11

First you created the file nos using cat command, then nos file given as input to sort command which prints sorted numbers. This is called input redirection.
In Linux (And in C programming Language) your keyboard, screen etc are all treated as files. Following are name of such files

Standard FileFile Descriptors numberUseExample
stdin0as Standard input Keyboard
stdout1as Standard output Screen
stderr2as Standard error Screen

By default in Linux every program has three files associated with it, (when we start our program these three files are automatically opened by your shell). The use of first two files (i.e. stdin and stdout) , are already seen by us. The last file stderr (numbered as 2) is used by our program to print error on screen. You can redirect the output from a file descriptor directly to file with following syntax
Syntax:
file-descriptor-number>filename

Examples: (Assemums the file bad_file_name111 does not exists)
$ rm bad_file_name111
rm: cannot remove `bad_file_name111': No such file or directory
Above command gives error as output, since you don't have file. Now if we try to redirect this error-output to file, it can not be send (redirect) to file, try as follows:
$ rm bad_file_name111 > er
Still it prints output on stderr as rm: cannot remove `bad_file_name111': No such file or directory, And if you see er file as $ cat er , this file is empty, since output is send to error device and you can not redirect it to copy this error-output to your file 'er'. To overcome this problem you have to use following command:
$ rm bad_file_name111 2>er
Note that no space are allowed between 2 and >, The 2>er directs the standard error output to file. 2 number is default number (file descriptors number) of stderr file. To clear your idea onsider another example by writing shell script as follows:

$ cat > demoscr
if [ $# -ne 2 ]
then
   echo "Error : Number are not supplied"
   echo "Usage : $0 number1 number2"
   exit 1
fi
ans=`expr $1 + $2`
echo "Sum is $ans"

Run it as follows:
$ chmod 755 demoscr
$ ./demoscr

Error : Number are not supplied
Usage : ./demoscr number1 number2

$ ./demoscr > er1
$ ./demoscr 5 7

Sum is 12

For first sample run , our script prints error message indicating that you have not given two number.

For second sample run, you have redirect output of script to file er1, since it's error we have to show it to user, It means we have to print our error message on stderr not on stdout. To overcome this problem replace above echo statements as follows
echo "Error : Number are not supplied" 1>&2
echo "Usage : $0 number1 number2" 1>&2
Now if you run it as follows:
$ ./demoscr > er1
Error : Number are not supplied
Usage : ./demoscr number1 number2

It will print error message on stderr and not on stdout. The 1>&2 at the end of echo statement, directs the standard output (stdout) to standard error (stderr) device.
Syntax:
from>&destination


Prev
Home
Next
Conditional execution i.e. && and ||
Up
Functions