Redirecting the standard I/O and error streams

We have an option to redirect standard input, output, and errors, for example, to a file, another command, intended stream, and so on. Redirection is useful in different ways. For example, I have a bash script whose output and errors are displayed on a standard output—that is, terminal. We can avoid mixing an error and output by redirecting one of them or both to a file. Different operators are used for redirection. The following table shows some of operators used for redirection, along with its description:

Operator

Description

>

This redirects a standard output to a file

>>

This appends a standard output to a file

<

This redirects a standard input from a file

>&

This redirects a standard output and error to a file

>>&

This appends a standard output and error to a file

|

This redirects an output to another command

Redirecting standard output

An output of a program or command can be redirected to a file. Saving an output to a file can be useful when we have to look into the output in the future. A large number of output files for a program that runs with different inputs can be used in studying program output behavior.

For example, showing redirecting echo output to output.txt is as follows:

$ echo "I am redirecting output to a file" > output.txt
$

We can see that no output is displayed on the terminal. This is because output was redirected to output.txt. The operator '>' (greater than) tells the shell to redirect the output to whatever filename mentioned after the operator. In our case, it's output.txt:

$ cat output.txt
I am redirecting output to a file

Now, let's add some more output to the output.txt file:

$ echo "I am adding another line to file" > output.txt
$ cat output.txt
I am adding another line to file

We noticed that the previous content of the output.txt file got erased and it only has the latest redirected content. To retain the previous content and append the latest redirected output to a file, use the operator '>>':

$ echo "Adding one more line" >> output.txt
$ cat output.txt 
I am adding another line to file
Adding one more line

We can also redirect an output of a program/command to another command in bash using the operator '|' (pipe):

 $ ls /usr/lib64/ | grep libc.so
libc.so
libc.so.6

In this example, we gave the output of ls to the grep command using the '|' (pipe) operator, and grep gave the matching search result of the libc.so library:

Redirecting standard input

Instead of getting an input from a standard input to a command, it can be redirected from a file using the < (less than) operator. For example, we want to count the number of words in the output.txt file created from the Redirecting standard output section:

$ cat  output.txt
I am adding another line to file
Adding one more line
$  wc -w < output.txt 
11

We can sort the content of output.txt:

$ sort < output.txt    # Sorting output.txt on stdout
Adding one more line
I am adding another line to file

We can also give a patch file as an input to the patch command in order to apply a patch.diff in a source code. The command patch is used to apply additional changes made in a file. Additional changes are provided as a diff file. A diff file contains the changes between the original and the modified file by running the diff command. For example, I have a patch file to apply on output.txt:

$ cat patch.diff    # Content of patch.diff file
2a3
> Testing patch command
$ patch output.txt < patch.diff   # Applying patch.diff to output.txt
$ cat output.txt    # Checking output.txt content after applying patch
I am adding another line to file
Adding one more line
Testing patch command

Redirecting standard errors

There is a possibility of getting an error while executing a command/program in bash because of different reasons such as invalid input, insufficient arguments, file not found, bug in program, and so on:

$ cd /root  # Doing cd to root directory from a normal user
bash: cd: /root/: Permission denied
Bash prints the error on a terminal saying, permission denied.

In general, errors are printed on a terminal so that it's easy for us to know the reason for an error. Printing both the errors and output on the terminal can be annoying because we have to manually look into each line and check whether the program encountered any error:

$ cd / ; ls; cat hello.txt; cd /bin/; ls *.{py,sh}

We ran a series of commands in the preceding section. First cd to /, ls content of /, cat file hello.txt, cd to /bin and see files matching *.py and *.sh in /bin/. The output will be as follows:

bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
cat: hello.txt: No such file or directory 
alsa-info.sh        kmail_clamav.sh    sb_bnfilter.py  sb_mailsort.py      setup-nsssysinit.sh    amuFormat.sh      kmail_fprot.sh   sb_bnserver.py    sb_mboxtrain.py    struct2osd.sh      core_server.py  kmail_sav.sh     sb_chkopts.py      sb_notesfilter.py  

We see that hello.txt doesn't exist in the / directory and because of this there is an error printed on the terminal as well, along with other output. We can redirect the error as follows:

$ (cd / ; ls; cat hello.txt; cd /bin/; ls *.{py,sh}) 2> error.txt
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
alsa-info.sh        kmail_clamav.sh    sb_bnfilter.py  sb_mailsort.py      setup-nsssysinit.sh    amuFormat.sh      kmail_fprot.sh   sb_bnserver.py    sb_mboxtrain.py    struct2osd.sh      core_server.py  kmail_sav.sh     sb_chkopts.py      sb_notesfilter.py  

We can see that the error has been redirected to the error.txt file. To verify, check the error.txt content:

$ cat error.txt
cat: hello.txt: No such file or directory

Multiple redirection

We can redirect stdin, stdout, and stderr together in a command or script or a combination of some of them.

The following command redirects both stdout and stder:

$ (ls /home/ ;cat hello.txt;) > log.txt 2>&1

Here, stdout is redirected to log.txt and error messages are redirected to log.txt as well. In 2>&1, 2> means redirect an error and &1 means redirect to stdout. In our case, we have already redirected stdout to the log.txt file. So, now both the stdout and stderr outputs will be written into log.txt and nothing will be printed on the terminal. To verify, we will check the content of log.txt:

$ cat log.txt
lost+found
sinny
cat: hello.txt: No such file or directory

The following example shows the stdin, stdout, and stderr redirection:

$  cat < ~/.bashrc > out.txt 2> err.txt

Here, the .bashrc file present in the home directory acts as an input to the cat command and its output is redirected to the out.txt file. Any error encountered in between is redirected to the err.txt file.

The following bash script will explain stdin, stdout, stderr, and their redirection with even more clarity:

#!/bin/bash
# Filename: redirection.sh
# Description: Illustrating standard input, output, error
# and redirecting them

ps -A -o pid -o command > p_snapshot1.txt
echo -n "Running process count at snapshot1: "
wc -l < p_snapshot1.txt
echo -n "Create a new process with pid = "
tail -f /dev/null &  echo $!    # Creating a new process
echo -n "Running process count at snapshot2: "
ps -A -o pid -o command > p_snapshot2.txt
wc -l < p_snapshot2.txt
echo
echo "Diff bewteen two snapshot:"
diff p_snapshot1.txt p_snapshot2.txt

This script saves two snapshots of all running processes in the system and generates diff. The output after running the process will look somewhat as follows:

$ sh redirection.sh
Running process count at snapshot1: 246
Create a new process with pid = 23874
Running process count at snapshot2: 247

Diff bewteen two snapshot:
246c246,247
< 23872 ps -A -o pid -o command
---
> 23874 tail -f /dev/null
> 23875 ps -A -o pid -o command
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.119.157