I/O Redirection

You are currently viewing I/O Redirection

We already know from our discussion under topic File Descriptors, Each process when created, by default is associated with three files with File Descriptor(FD) numbers 0, 1 and 2. If process opens additional files further, descriptor numbers from 3 onwards are assigned to them. The default three files connected with the process are:

FD No. Default File Connection File Type FD Name Description
FD 0 Keyboard (R)ead-only stdin Standard Input
FD 1 Monitor Screen or Terminal (W)rite-only stdout Standard Output
FD 2 Monitor Screen or Terminal (W)rite-only stderr Standard Error
FD 3+ None R/W/RW FILENAME Other Files

By convention, a command(or process) reads its input from FD0(stdin), prints normal output to FD1(stdout) and error output to FD2(stderr). That is, by default, the first file descriptor FD0 is for reading and the other two file descriptors FD1 and FD2 are for writing. Same is depicted in the image below:

Redirection01

Any file opened by a process(including default three) can be redirected, i.e. reassigning one of the file descriptor to another file(or a pipe, or anything permissible). Redirection means capturing output from a file, command, program, script, or even code block within a script and sending that output as input to another file, command, program, or script.

Using Redirection, process output(both stdout and stderr) messages can be captured in the form of file contents, or may be forwarded to a device or can be completely discarded.For quietly discarding stdout and stderr, they both must be forwarded to a special device file /dev/null

Following table lists basic redirection operators and their function:

Redirection (Operators) Function
>FILE OR 1>FILE Redirect stdout to a FILE (overwrite mode)
$ cat /etc passwd > /tmp/outputFile (OR)
$ ping -c4 localhost > /tmp/outputFile
Note: Second command will overwrite the output saved by first command in "outputFile".
>>FILE OR 1>>FILE Redirect stdout to a FILE (append mode)
$ ps >> /tmp/outputFile
Note: Above commmand will append its output to the contents of "outputFile"
2>FILE Redirect stderr to a FILE (overwrite mode)
$ abc123xyz 2> /tmp/outputFile
Note: Error Message "abc123xyz: command not found" will get saved in "outputFile" overwriting the previous content of the file.
2>>FILE Redirect stderr to a FILE (append mode)
$ ls abc123xyz 2>> /tmp/outputFile
Note: Error Message generated by above command will get appended to the contents of "outputFile".
>/dev/null OR 1>/dev/null Discarding stdout
$ find /etc -name passwd > /dev/null
Note: Only Error Messages will get printed on screen, valid output will get dumped to /dev/null file or you may say, it will get nullified by pseudo device file /dev/null.
2>/dev/null Discarding stderr
$ find /etc -name passwd 2> /dev/null
Note: Only valid search results will get printed on screen, Error Messages will get dumped to /dev/null file or you may say, it will get nullified by pseudo device file /dev/null.
&>FILE Redirect combined stdout & stderr to one FILE (overwrite mode)
$ ls -l /etc/{passwd,group,nosuchfile1,nosuchfile2} &> /tmp/outputFile
Note: Both stdout (valid output) and stderr(error messages) will get saved in "outputFile", overwriting the contents of file.
&>>FILE Redirect combined stdout & stderr to one FILE (append mode)
$ tail -n3 /etc/{passwd,group,shadow} &>> /tmp/outputFile
Note: Both stdout (valid output) and stderr(error messages) will get appended to the contents of "outputFile".
>FILE 2>&1 Redirect combined stdout & stderr to one FILE (overwrite mode)
$ find /etc -name passwd > /tmp/outputFile 2>&1
Note: Both stdout (valid output) and stderr(error messages) will get saved in "outputFile", overwriting the contents of file.
>>FILE 2>&1 Redirect combined stdout & stderr to one FILE (append mode)
$ ls -l /etc/{passwd,group,nosuchfile1,nosuchfile2} >> /tmp/outputFile 2>&1
Note: Both stdout (valid output) and stderr(error messages) will get appended to the contents of "outputFile".

Note: Difference between &> and 2>&1
&> Operator redirects both stdout and stderr to FILE from their respective channels FD1 & FD2, whereas 2>&1 redirects stdout from its respective channel FD1 but forwards stderr from the same channel as stdout i.e. FD1.
Both, generates same output while redirecting to a FILE, but if there is a requirement to forward both stdout and stderr through a pipe(discussed later) from one command(process) to another, then the second one (2>&1) is used because pipe does not allow data to be passed through stderr channel i.e. FD2. Therefore by using (2>&1) stderr is redirected through the same channel as stdout as shown in images below:

  1. First and Third image depicts the case of redirection using &>
  2. Second and Fourth image depicts the case of redirection using 2>&1

Redirection0203

Note: Few important cases to consider:

  1. Case X>Y
    X is a file descriptor, which defaults to 1, if not explicitly set.
    Y is a Filename.
    File descriptor X is redirected to file Y
  2. Case X>&Y
    X is a file descriptor, which defaults to 1, if not explicitly set.
    Y is another file descriptor
    Redirects file descriptor X to Y
    All output of file pointed to by X gets sent to file pointed to by Y
    If X not explicitly set, then Case X>&Y becomes >&Y i.e. Redirects, by default, file descriptor 1 (stdout) to Y. It means stdout gets sent to file pointed to by Y.
  3. Case 0<Filename or <Filename
    Accept input from file.
    Companion command to ">", and often used in combination with it.
    For example $ grep processor < /proc/cpuinfo
  4. Closing File Descriptors
  • N<&- For closing input file descriptor N. For Example:
    0<&- or <&- can be used to close stdin
    $ exec 0<&- Closing stdin, will close the entire terminal.
  • N>&- For closing output file descriptor N. For Example:
    1>&- or >&- can be used to close stdout
    $ exec 1>&- Closing stdout, will result in error message "write error: Bad file descriptor"
    $ exec 1>&2 or $ exec 1>&0 for re-opening or restoring stdout.
  1. Case Z<>Filename
    Open file "Filename" for Reading and Writing and assign file descriptor Z to it.
    If file "Filename" does not exist, create it.
    If file descriptor Z is not specified, default to FD0 (stdin).
    For example(See output image below the code for more clarity):
echo "line1 line2" > txtFile
cat txtFile              #See contents of txtFile
exec 3<> txtFile         #Open/Create file "txtFile" and assign FD3 to it
read -n 5 <&3            #Read only 5 characters
echo >&3                 #Overwrite 6th character (space) with newline character
exec 3>&- (or exec 3<&-) #Close FD3
cat txtFile              #See contents of txtFile and notice the changes made to it.

FD06

Leave a Reply