Bash — pipes and redirections
stdin,stdout and stderr
When bash starts creates three file descriptors, these file descriptors point not to a file but in a terminal device usually in the format of /dev/tty[n]
stdin: file descriptor 0, stdin stands for standard input and means incoming to the terminal data, the standard device to enter data to the terminal is the keyboard.
stdout: file descriptor 1, stdout stands for standard output and means printing to the terminal normal messages, or text.
stderr: file descriptor 2, stderr stands for standard error and means printing error messages to the terminal.
redirecting output
The stdout and stderr can redirected to a file if we want, to do this we need to use redirection operators
The >operator
The > operator redirects the process output to a file, if the file does not exist will be created, if exists will be overwriten.command > file.txt
Another way to do this is to write the full version, using the file descriptorcommand 1> file.txt
The >>operator
The >> operator redirects the process output to a file, if the file does not exist will be created, if exists the output will be appended to the end of the file.command >> file.txt
How to redirect stderr to a file
By specifying the file descrtiptor of stderr we can redirect stderr to a filecommand 2> file.txt
How to redirect both stderr and stdout to a file
There are two ways, the simple way works to modern versions of bash and uses the &> operatorcommand &> file.txt
And the old fashion way that is guarrantided to work with all bash versionscommand >file 2>&1
Both versions mean append stderr to stdout and stdout to a file.
How to redirect stderr and stdout to separate filescommand 2>error.txt 1>std.txt
How to discard output
redirecting stdout and/or stderr of a process to /dev/null is very helpful when we want to discard all output of a process.command > /dev/null
redirecting stdin
Create a file named a.txt with the following contentaa
bb
cc
dd
If we want to count the number of lines of a.txt we could use$ wc -l a.txt
4
But wc accepts input from stdin as well and we can use the < operator to redirect input from a file.$ wc -l < a.txt
4
Combining stdin and stdout
There might be cases that we need to process input and store the ouput to a file, create file b.txt with contentsgg
aa
yy
bb
pp
run the followingsort < b.txt > c.txt
cat c.txt
aa
bb
gg
pp
yy
pipes
Pipes enabe communication between processes by piping stdout or stderr, or both to the stdin of another process, the pipe symbol is |
To redirect stdout of a process to stdin of another the usage is very simple$ cal | wc -l
8
piping stderr to sdtout
pipes only accept stdout and not stderrcp dd.txt ddf.txt | grep -io stat
cp: cannot stat 'dd.txt': No such file or directory
To combine both stdout and stderr you can use 2>&1$ cp dd.txt ddf.txt 2>&1 | grep -io stat
stat
To discard stdout to /dev/null and convert stderr to stdout in order to make it “pipeable” you can use the following syntax, file gg.txt intensionally does not exist in order to cause stderr outputcp -v gg.txt ddf.txt 2> /dev/fd/1 1> /dev/null | grep -o stat
stat
I hope you found the article useful :)