Objective
While individual Linux commands are powerful tools in their own right, the true strength of the Linux command line lies in our ability to connect these commands, creating what we call command pipelines.
Each Linux command is designed to do one thing and do it incredibly well, So by being able to combine together lots of powerful & feature rich building blocks you can create very powerful workflows and automation solutions.
However, to effectively chain commands together and build these sophisticated workflows, we must first understand the fundamental mechanics of how Linux commands receive input and produce output. This knowledge forms the foundation for all advanced command-line operations and is critical for anyone looking to master Linux CLI.
In this article, you'll learn:
The different ways a command can take input and give output, creating a mental model for data flow in Linux
How to understand and work with the three Standard data streams for Linux commands
Practical techniques to redirect these data streams from their default locations to files, other commands, or even other terminals
Standard Data Streams in Linux
Think of each Linux command as a small computer program. Just like any program, it needs some information to work with (input), it does something with that information (processing), and then it shows you the results (output).
For example, when you use the calculator app on your phone, you give it numbers (input), it adds or multiplies them (processing), and then it shows you the answer (output).
Linux commands work the same way! The diagram below shows you exactly how commands receive their inputs and send their outputs. Understanding this simple flow is the first step to connecting multiple commands together to build workflows.
Most Linux command operates with three standard data streams:
Standard Input (stdin - 0)
The default input stream that provides data to a command
The Standard input date stream is connected by default to the Keyboard, So by default you as the user providing input to the standard input data stream.
Often used for interactive input or feeding data to commands
File descriptor: 0 (more about this later)
Example: When you type “cal 2025” on your keyboard, you're providing input through the standard input stream (stdin). The keyboard serves as the default input device, sending your command to the Linux system through file descriptor 0, which then processes your request via cal program to display the 2025 calendar for you.
Standard Output (stdout - 1)
The default output stream where a command sends its normal output
The Standard output data stream is connected by default to your Terminal window, and this is how you see the output/result of commands you type.
Contains the expected output from commands when they execute successfully
File descriptor: 1 (more about this later)
Example: After running “cal 2025” command, the calendar application processes your request and sends the formatted calendar data for 2025 to the standard output stream (stdout). This output travels through file descriptor 1 and appears on your terminal screen, which is the default destination for all standard output."
Standard Error (stderr - 2)
A separate output stream specifically for error messages
The Standard error data stream is connected by default also the terminal screen just like the Standard output data stream, and this is how you see the errors on you terminal when you mistype a command.
Separating errors from normal output enables more flexible handling
File descriptor: 2 (more about this later)
Example: "When you mistype a command like “cal xyz” in your terminal, the cal program recognizes that 'xyz' is not a valid year or month. Instead of sending normal calendar output to standard output (stdout), it generates an error message like 'cal: not a valid year xyz' and sends this through the standard error stream (stderr). This error message travels through file descriptor 2 and appears on your terminal screen, which serves as the default destination for both standard output and standard error streams. This separation allows programs to distinguish between normal results and error conditions."
Now, Let's create a clear CLI example that shows standard input from keyboard and standard output/error to terminal:
user@linux:~$ date
Mon Apr 7 15:30:45 EDT 2025
In this “date” example:
Standard Input: You type the command “date
”
using your keyboard and press EnterStandard Output: The current date and time appear on your terminal screen
Processing: In between, the date command/program gets the current time from your system
This shows the default flow where your keyboard provides input to the system, the command/program processes that input (in this case, by checking the system time), and then displays the result on your screen.
If we try a version with an error:
user@linux:~$ date --invalid-option
date: invalid option -- '-invalid-option'
Try 'date --help' for more information.
Now we see:
Standard Input: You type an incorrect command with your keyboard
Standard Error: The error message appears on your terminal screen
Both examples show how, by default, your keyboard is the input source and your terminal screen is where both normal output and error messages appear.
Summary
These three streams are the building blocks for understanding how Linux commands handle information. Think of it like this: your keyboard is where commands get their input, and your screen is where you see both the normal results and any error messages. But here's where it gets really interesting, Linux lets you change where these streams go! Instead of typing on your keyboard, you can make a command read from a file. Instead of showing results on your screen, you can save them to a file or send them to another command. This flexibility is what makes Linux so powerful for creating custom workflows.
There is 1 way to get data into a command using standard input date stream.
There are 2 ways to get output from a command, using standard output and standard error data streams.
Standard input data stream is connected by default to your keyboard (we will see how to change that later)
Standard output data stream is connected by default to your terminal window (we will see how to change that later)
Standard error data stream is connected by default to your terminal window (we will see how to change that later)
Data streams (Standard input, Standard output and Standard Error) can be redirected from their default locations to whatever you wish
You can redirect the standard output of one command to the standard input of another command in a process known as piping
Redirection and Piping are incredibly powerful abilities that Linux gives us, and being able to use them effectively will basically give you super powers for interacting with the CLI.
Standard Data Streams Redirection
Now that you understand how Linux commands handle input and output using standard data streams (stdin, stdout, and stderr), let's dive into one of Linux's most powerful features: redirection.
Think of redirection as changing the path of these data streams. By default, your keyboard feeds into stdin, and both stdout and stderr display on your terminal screen. But what if you want to:
Save command output to a file instead of displaying it on screen?
Use the contents of a file as input instead of typing it all on your keyboard?
Save some error messages to file for later troubleshooting?
This is where redirection comes in! Redirection lets you control where these streams come from and where they go. It's like installing pipes in a house - you can change where water comes from and where it flows to.
Linux provides several special operators that let you redirect these streams:
1> - Redirects standard output to a file (overwrites existing file content each time)
1>> - Redirects standard output to a file (appends existing file content each time)
< - Redirects standard input to come from a file instead of keyboard
2> - Redirects standard error to a file (overwrites existing file content each time)
2>> - Redirects standard error to a file (appends existing file content each time)
Examples of Output Redirection
Standard Output Redirection (Overwriting Mode)
Let's see how 1>
(or simply >
) works by redirecting the output of the date
command to a file:
# First, let's redirect the date output to a file
$ date 1> output.txt
# Let's check what's in the file (basically cat command display file content)
$ cat output.txt
Mon Apr 7 15:30:45 EDT 2025
# Now let's run the cal command and redirect to the same file
$ cal 1> output.txt
# Check the file again - notice the previous content is gone!
$ cat output.txt
April 2025
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Notice how the calendar output completely replaced the date information! This is because 1> truncates (empties) the file before writing new content to it. The original date information is removed totally.
Standard Output Redirection (Append Mode)
Now let's see how 1>>
(or simply >>
) works by appending output instead of overwriting:
# First, write the date to a file
$ date 1>> log.txt
# Check the file contents
$ cat log.txt
Mon Apr 7 15:33:22 EDT 2025
# Now add the calendar output to the same file
$ cal 1>> log.txt
# Check again - both outputs are preserved!
$ cat log.txt
Mon Apr 7 15:33:22 EDT 2025
April 2025
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
With 1>>
, the calendar output is added after the date information, preserving both. This is perfect for creating logs or collecting related outputs together.
These simple examples clearly demonstrate how the choice between >
and >>
can make a big difference in how your command outputs are handled!
Standard Error Redirection (Overwriting Mode)
Let's use the date
command again but this time with an invalid option to generate an error and redirect the standard error output to file using 2> :
# First, try running date with an invalid option to generate an error
$ date --invalid-option
date: invalid option -- '--invalid-option'
Try 'date --help' for more information.
# Now redirect the error message to a file
$ date --invalid-option 2> errors.txt
# Notice nothing appeared on screen - the error went to the file
$ cat errors.txt
date: invalid option -- '--invalid-option'
Try 'date --help' for more information.
# Try another error, using a non-existent format option
$ date +%invalid 2> errors.txt
# Check the file - the previous error is gone!
$ cat errors.txt
date: invalid format %invalid
Just like with standard output, 2>
overwrites the previous content each time the standard error output is being redirected.
Error Redirection (Append Mode)
Now let's see how 2>>
works by appending output instead of overwriting:
# Append an error message to a log file
$ date --invalid-option 2>> error_log.txt
# Add another error
$ date +%invalid 2>> error_log.txt
# Check the file - both errors are preserved
$ cat error_log.txt
date: invalid option -- '--invalid-option'
Try 'date --help' for more information.
date: invalid format %invalid
Combining Standard Output and Standard Error Redirection (in Single Command)
You can redirect both streams in the same command to two files or to single file:
Redirecting to Separate Files
# Send normal output to one file and errors to another
$ date 1> output.txt 2> errors.txt
# The date command succeeded without errors
$ cat output.txt
2025-04-07
$ cat errors.txt
(empty file because there were no errors)
# Now try with an intentional error
$ date --invalid-option 1> output.txt 2> errors.txt
# Check both files
$ cat output.txt
(empty file because the command failed)
$ cat errors.txt
date: invalid option -- '--invalid-option'
Try 'date --help' for more information.
This separation is incredibly useful for scripts and automated tasks, where you might want to process successful results differently from errors, so you have two files to store the output for your standard data streams (output and errors).
Examples of Input Redirection
Redirecting Standard Input (stdin)
So far, we've seen how to redirect standard output and standard error to files. Now, let's explore how to redirect standard input from a file instead of typing commands on the keyboard.
Standard input redirection allows you to feed data into a command from a file rather than from your keyboard. This is done using the <
(or 0<
) operator.
# First, let's create a file called input.txt with the famous Hello World!
$ nano input.txt
Hello World!
^O # Press Ctrl+o to save the content of input.txt
# Now let's use the cat command, with redirected standard input to input.txt
$ cat 0< input.txt
Hello World!
In this example, instead of reading from standard input (keyboard), the cat
command reads from the file input.txt because we redirected its standard input using the 0<
operator. The command displays "Hello World!" on the screen through its standard output.
Here is a mini challenge, I want you to get “cat” to read standard input from input.txt file, and redirect that output to hello.txt file!
Here's a simple solution to your mini challenge:
# Using cat to read from input.txt and redirecting output to hello.txt
$ cat 0< input.txt 1> hello.txt
# Let's check if hello.txt now contains the content
$ cat hello.txt
Hello World!
In this mini challenge:
cat 0< input.txt
- The cat command reads from input.txt (instead of the keyboard)1> hello.txt
- The output from cat is redirected to hello.txt (instead of the screen)
This demonstrates how you can chain multiple redirections together in a single command - redirecting both the input and output streams. The content "Hello World!" flows from input.txt through the cat command and into hello.txt without ever appearing on your screen.
This is a simple but powerful example of how redirection gives you complete control over data flow in the Linux command line!
Terminal-to-Terminal Redirection in Linux
In Linux, each terminal session gets assigned a pseudo-terminal (pts) device file:
When you open a terminal window, the system assigns it a device file like
/dev/pts/0
,/dev/pts/1
, etc.These files act as interfaces to your terminal sessions
You can read from and write to these files just like any other file
This allows for communication between different terminal sessions
To find which device file corresponds to your current terminal:
$ tty
/dev/pts/0
The output shows your current terminal's device file.
Terminal-to-Terminal Redirection Example
Let's say you have two terminal windows open:
Terminal 1:
/dev/pts/0
Terminal 2:
/dev/pts/1
Step 1: Verify terminal devices
In each terminal, run the tty
command to confirm their device paths.
Step 2: Send a message from Terminal 1 to Terminal 2
# In Terminal 1
$ echo "Hello from Terminal 1!" > /dev/pts/1
The message "Hello from Terminal 1!" will immediately appear in Terminal 2, even though you executed the command in Terminal 1.
or you can redirect any command standard output to the second terminal:
# In Terminal 1
$ date > /dev/pts/1
The output of the date command will appear in Terminal 2 instead of Terminal 1.
Summary
Linux treats all input and output as data streams, with three standard streams: stdin (0), stdout (1), and stderr (2). Redirection operators let you control where these streams flow. The >
operator redirects output to a file (overwriting), while >>
appends to existing content. The <
operator reads input from a file instead of the keyboard. You can combine these operators to create powerful data pipelines. Linux even allows redirecting between terminals by treating them as files in /dev/pts/
. Understanding redirection gives you precise control over data flow in the command line, making complex tasks simpler and more efficient.
Standard input, Standard output and standard error are Data Streams
Using redirection you can control where those streams “flow”
Standard input =0, Standard output =1, Standard error =2
Be careful of truncating your files!
> will overwrite file before writing to it
> > will append to what’s already in the file you are redirecting to