Monday, August 13, 2012

STDIN, STDOUT and STDERR


/dev/stdin standard input

/dev/stdout standard output

/dev/stderr standard error 


STANDARD INPUT AND OUTPUT

Commands take a stream of characters as input (input stream) and generate a stream of characters as output (output stream). These are called streams as they have no internal structure. Even the NEWLINE character is not treated differently.

While the input stream for a command forms standard input, the output stream of a command is called standard output. The UNIX shell usually treats the terminal keyboard as standard input and the terminal screen as standard output. However, standard input and output may be redirected to files.

STANDARD ERROR

The system also provides for a third stream, the standard error stream. Most commands use the standard error stream to display error messages. By default, standard error is displayed on the standard output.standard error may be redirected to an output file using the appropriate file descriptor.

A file descriptor is a number associated with a file of data.

0 - standard input (/dev/stdin -> /proc/self/fd/0)
1 - standard output (/dev/stdout -> /proc/self/fd/1)
2 - standard error (/dev/stderr -> /proc/self/fd/2)

$ cat file1 1> newfile 2> errmesg

This will write the contents of file1 to newfile. Any error messages are redirected to the errmesg file.

Now, lets look at some examples of how the STDIN, STDOUT and STDERR work.


$ ls -ltr
total 20
-rw-r--r-- 1 oracle dba   45 Jan 12 23:19 file1

$ cat file1
this is line 1
this is line 2
this is line 3

$ cat file1 > file1.out 2> file1.err    

The above command will redirect the contents of file1 to file1.out while any error/warning messages will be written to file1.err. This command can also be written as shown below where the 1> and 2> denote the STDOUT and STDERR numerically. The 0> for STDIN is not really needed since by default the STDIN is either a keyboard to key in commands or contents from a file.

$ cat file1 1> file1.out 2> file1.err


$ ls -ltr
total 20
-rw-r--r-- 1 oracle dba   45 Jan 12 23:19 file1
-rw-r--r-- 1 oracle dba   45 Jan 12 23:20 file1.out
-rw-r--r-- 1 oracle dba    0 Jan 12 23:20 file1.err


$ cat file1.out
this is line 1
this is line 2
this is line 3

$ cat file1.err

Lets look at another example, file2 does not exist but the redirectional error/warning messages will not be displayed on the screen


$ cat file1.err

$ cat file2
cat: file2: No such file or directory

$ cat file2 1> file2.out 2> file2.err

$ ls -tlr file2*
-rw-r--r-- 1 oracle dba    0 Jan 12 23:21 file2.out
-rw-r--r-- 1 oracle dba   38 Jan 12 23:21 file2.err

$ cat file2.out

$ cat file2.err
cat: file2: No such file or directory

A point to be noted is file2.err now has the error message that was otherwise displayed on screen

Let us now avoid the STDOUT and just work with STDIN and STDERR

$ cat file5
cat: file5: No such file or directory

$ cat file5 2> file5.err

$ ls -tlr file5*
-rw-r--r-- 1 oracle dba   38 Jan 12 23:24 file5.err

$ cat file5.err
cat: file5: No such file or directory

There is also a possibility of appending something to the STDERR like below

$ cat file6
cat: file6: No such file or directory

$ cat file6 2>> file5.err

$ cat file5.err
cat: file5: No such file or directory
cat: file6: No such file or directory

Now, comes that most interesting part that we see most often in production environments. The 2>&1, which means that the output going to the file descriptor 2 (STDERR) should go to the same place as file descriptor 1 (STDOUT). It can better be understood with an example.

$ cat file7
cat: file7: No such file or directory

$ cat file7 2>&1
cat: file7: No such file or directory

$ cat file7 1> file7.out 2>&1

The above command tries to redirect (1>) the contents of a (non-existing) file,file7,to file7.out (STDOUT) - also any error/warning messages that are intended for STDERR should also be redirected (1>) to file7.out (2>&1)

$ ls -tlr file7*
-rw-r--r-- 1 oracle dba   38 Aug 12 23:30 file7.out

$ cat file7.out
cat: file7: No such file or directory