Let's start with the basics. What do the standard streams do?
A program running in a Unix-like operating system can read and write from/to one of the 3 standard streams:
Every open file in a Unix-like operating system is assigned a file descriptor (a positive integer), which is used to access the file. The standard streams are treated as files and operating system assigns the file descriptors to them, which for stdin, stdout, and stderr are 0, 1, and 2, respectively.
An example of reading from stdin and writing to stdout in the bash shell:
read MY_NAME #we prompt the user for the name and read it from stdin John Doe #the user enters the name echo $MY_NAME #we write the user's name to stdout
The destination of stderr is commonly the text terminal. So, if the program writes an error message to stderr, you'll see it in the text terminal:
You'll see the following error message from the cat program: cat: idontexist: No such file or directory.
We can redirect standard streams. Let's redirect whatever a program writes to stderr to a file:
cat ./idontexist 2>stderr.txt
cat writes an error message to stderr, because the file idontexist doesn't exist. The part 2>stderr.txt redirects whatever is written to stderr to the stderr.txt file (in other words, whatever is written to the file descriptor 2 should go into the stderr.txt).
We could do the same with stdout:
echo "Hello World" 1>stdout.txt
We redirect whatever the echo program writes to stdout (file descriptor 1) to the stdout.txt file.
The single > (greater than) operator overwrites the file if it already exists. In order to append to an existing file instead, use the double > (greater than) operator:
echo "Hello World" 1>>stdout.txt
You can send the file contents to the program through the standard input using the < (less then) operator, if the program supports this:
echo "Hello World" 1>example.txt cat 0<example.txt
We've sent the contents of example.txt to the file descriptor 0. This way, cat will receive only the contents, it won't know which file you read.
Also, we can combine the redirections. Let's use the wc program to count the number of words in one file and write this number to another file:
echo "This file has five words" 1>words.txt wc -w 0<words.txt 1>words-count.txt cat words-count.txt
Every program that you run in the terminal has 3 standard streams connected to it: stdin, stdout, and stderr with the 0, 1, and 2 file descriptors, respectively. We can redirect a stream to a file or to another stream using the > (greater than) or >> (double greater than) operators. We can read a file to the standard input stream using the < (less than) operator.