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 |
| |
| |
| |
| |
|
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:
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
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
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
3.133.119.157