The Linux/Bash shell has three data streams that you can tap into when executing commands – stdin, stdout, and stderr. Here’s how to use them.
stdin, stdout, stderr allow for the display of text in the console, and the data being output each stream can be directed into other programs.
These are referred to as Standard Streams.
What is stdin (Standard Input)?
Text input stream.
Applications can accept text via stdin as input.
What is stdout (Standard Output)?
The text output stream of a program.
Applications send data to other programs (or to the console for viewing) via stdout.
What is stderr (Standard Error)?
The text error output stream of a program.
If a program encounters an error, it should send the data regarding the error out via the stdout stream.
…Yeah, But What Does that Actually Mean?
A computer program does things with input and output data – for example, a program may accept a maths equation and provide the solution to it.
You need a way to get the equation IN to the program and a way to get the answer OUT of the program. You also want to know if the equation was unsolvable, so you want to see any ERRORs generated, separate from any other OUTPUT.
That’s stdin, stdout, and stderr.
Because having everything work the same way makes life easier, these inputs, outputs, and error streams have become standardized so that applications built for the command line all behave the same way.
Hence, Standard Streams. Each stream has a numerical identifier from 0-3:
Redirecting/Piping from stdin, stdout, stderr in Bash/Shell
You typing into the Linux shell is a stream of text – you type, and the text stream is fed into the console input.
An application runs, and the text data output from it is fed into the console for display so that you can read it.
This is all the default behavior when working on the console, but it can be changed. Streams can be redirected – for example, the program’s output can be directly streamed into a file rather than to the console for viewing.
The output from one program can be redirected into the input of another program directly.
Here are some basic examples using redirection and piping.
Usually, the echo command will print text to the console:
echo "hello there!"
The stdout of the echo program is taking its default path to be displayed on your screen.
Redirection lets you send it somewhere else. Here, it is sent to a file:
echo "hello there!" > test.txt
A file called text.txt will be created containing the text “hello there!” (watch out, if the file already exists, it will be overwritten).
You can append files by using >> instead of >
Next, let’s redirect stdin using <
cat < test.txt
The cat command reads the contents of text.txt into its stdin stream and then does what the cat command is designed to do – prints the data supplied to it to stdout, which by default is the console for viewing. So, this will simply output hello there! to the console.
The data in the file was directed to stdin for the cat command – it was redirected.
This is kind of cheating, the cat command will try to read from a filename passed to it as a parameter without piping, but it’s the simplest command for the purposes of this example.
You can redirect stdin and stdout in the same command:
cat < test.txt > output.txt
stdin is being redirected, reading test.txt into the cat program, and the stdout from the cat program is being directed into a file called output.txt.
Again, this is cheating as it’s really just using the cat command to copy a file, but it is a simple example that doesn’t rely on explaining other commands.
Finally, you can redirect the stderr stream by specifying the unique stream number we want to read from (as stdout is the default, it doesn’t need to be specified):
cat nofile.txt 2> error.txt
stdout is identified with the number 2 – if cat generates an error, it will be sent via this stream and into the file error.txt.
The example above will create a file called error.txt containing the text:
cat: nofile.txt: No such file or directory
…as the cat command couldn’t find the file nofile.txt.
In the example above, the stderr stream was identified by its numeric identifier – this means you can redirect stdout and stderr in the same command by specifying which one you wish to redirect:
echo "hello there! 1>test.txt 2>error.txt
Above, stdout is sent to test.txt, and stderr is sent to error.txt.
Piping is the same as redirection, but it only deals with stdin, and stdout errors are ignored.
echo "hello there!" | cat
Here, the pipe (|) pipes (redirects) stdout of the echo command to stdin of the cat command.
Working with command-line applications may seem unintuitive initially, but they are powerful tools when automating tasks. stdin, stdout, and stderr – the standard streams are the cornerstone of this flexibility – you can chain together commands to create complex workflows that can handle almost any task.