Every Linux program interacts with three primary input/output streams:
Standard Input (stdin) – By default, takes input from the keyboard.
Standard Output (stdout) – Displays results on the screen unless redirected.
Standard Error (stderr) – Shows error messages separately from standard output.
Understanding these streams enables users to redirect and manipulate input and output efficiently using various I/O redirection techniques.
Redirecting Standard Output (stdout)
By default, the output of a command is displayed on the screen, but we can redirect it to a file using >:
ls -l /usr/bin > ls-output.txt
This saves the directory listing of /usr/bin in ls-output.txt instead of printing it on the terminal.
Checking the Output File
ls -l ls-output.txt
If successful, the file contains the command output and its size reflects the generated data. To view the contents:
less ls-output.txt
Handling Errors with Standard Error (stderr)
Not all output is standard output. Programs like ls send error messages to stderr, meaning they will still appear on-screen even if stdout is redirected.
Example: Redirecting Output with an Invalid Directory
ls -l /bin/usr > ls-output.txt
If /bin/usr does not exist, an error message appears on the screen instead of in ls-output.txt. To verify the file size:
ls -l ls-output.txt
Output shows:
bash
-rw-rw-r-- 1 user user 0 ls-output.txt
The file is empty because stdout was redirected while stderr remained on-screen.
Appending Output Instead of Overwriting
By default, > overwrites existing files. If we want to append output instead, use >>:
ls -l /usr/bin >> ls-output.txt
Using >>, the output adds to the file rather than replacing its contents.
Example: Appending Multiple Times
ls -l /usr/bin >> ls-output.txt ls -l /usr/bin >> ls-output.txt ls -l /usr/bin >> ls-output.txt ls -l ls-output.txt
Now, ls-output.txt grows in size after each execution.
In Linux, commands send their main output to standard output (stdout) and error messages to standard error (stderr). By default, both streams are displayed on the screen, but users can redirect them to files or suppress them entirely.
This article explains how to redirect standard error (stderr), capture both output streams together, and dispose of unwanted output using /dev/null.
Redirecting Standard Error (stderr)
Since standard error is file descriptor 2, we use 2> to redirect error messages to a file:
ls -l /bin/usr 2> ls-error.txt
This redirects only error messages (if any) to ls-error.txt while keeping standard output on the screen.
Redirecting Both Standard Output (stdout) and Standard Error (stderr) Together
Sometimes, users want both outputs to be saved in one file. There are two methods to achieve this:
Traditional Method (Compatible with Older Shells)
ls -l /bin/usr > ls-output.txt 2>&1
Explanation:
Redirects stdout to ls-output.txt.
Redirects stderr (file descriptor 2) to match stdout (file descriptor 1) using 2>&1.
Newer Bash Method (Simpler Syntax)
ls -l /bin/usr &> ls-output.txt
The &> notation combines both streams into one file without needing 2>&1.
Appending Instead of Overwriting
To append output to an existing file rather than overwriting, use >>:
ls -l /bin/usr &>> ls-output.txt
Now, each execution adds the new output instead of replacing the existing data.
Disposing of Unwanted Output with /dev/null
Sometimes, users want to suppress error messages entirely. The best way to discard unwanted output is by redirecting it to /dev/null, known as the bit bucket:
ls -l /bin/usr 2> /dev/null
Here, all error messages are discarded, and nothing is saved.
Unix Culture: /dev/null
The bit bucket (/dev/null) is an old Unix concept used to represent complete disposal of data. In tech communities, saying "Your request was sent to /dev/null" humorously means it was ignored entirely.
Standard input (stdin) is one of the three fundamental I/O streams in Linux. It allows programs to receive input, typically from the keyboard, but can be redirected from files or other sources.
This article explores how to redirect standard input, using the cat command as an example, and demonstrates how input redirection improves efficiency in text processing.
Using cat to Read Files
The cat command copies the contents of a file to standard output (stdout):
cat filename
For example, displaying the contents of ls-output.txt:
cat ls-output.txt
This prints the file contents without paging.
Joining Multiple Files with cat
If a large file has been split into parts, cat can rejoin them:
cat movie.mpeg.0* > movie.mpeg
Since wildcards sort files automatically, the parts are joined in the correct order.
Using cat with Standard Input (stdin)
When cat runs without arguments, it waits for input from the keyboard:
cat
It behaves as an interactive prompt, allowing users to type text.
Ending Input with Ctrl+D
To signal the end of input (EOF), press Ctrl+D:
cat The quick brown fox jumped over the lazy dog.
Pressing Ctrl+D submits the input and displays the text.
Creating a File Using Input Redirection
The > operator allows users to save standard input into a file:
cat > lazy_dog.txt The quick brown fox jumped over the lazy dog.
This stores the text in lazy_dog.txt.
Verifying the File Contents
To confirm the contents:
cat lazy_dog.txt
Output:
bash
The quick brown fox jumped over the lazy dog.
Redirecting Standard Input (<) from a File
Instead of typing text, users can redirect a file as input:
cat < lazy_dog.txt
This reads lazy_dog.txt and behaves identically to passing it as an argument. While not particularly useful for cat, other commands make better use of input redirection, as we will see later.
Pipelines allow Linux commands to process data efficiently by passing standard output (stdout) from one command into standard input (stdin) of another using the pipe operator |. By chaining multiple commands, users can filter, manipulate, and analyze data dynamically.
This article explores how to use pipelines, apply filters like sort, uniq, grep, and utilize tee for saving pipeline output.
Basic Pipe Usage (|)
A pipeline connects two or more commands:
command1 | command2
Example: Display paged output using less:
ls -l /usr/bin | less
Here, ls -l /usr/bin lists files, and less allows scrolling through results page by page.
Sorting Output with sort
To list all executable programs in /bin and /usr/bin, sort them, and view results:
ls /bin /usr/bin | sort | less
Using sort, the output is now merged into a single sorted list.
Understanding > vs. |
While > redirects output to a file, | passes output to another command:
ls > output.txt # Redirects to a file ls | less # Passes output to less
Using > incorrectly can overwrite system files, causing severe issues.
Removing Duplicates with uniq
uniq filters duplicate entries when used after sorting:
ls /bin /usr/bin | sort | uniq | less
To view only duplicates, use -d:
ls /bin /usr/bin | sort | uniq -d | less
Counting Output Lines with wc
To count items in a sorted list, use wc -l:
ls /bin /usr/bin | sort | uniq | wc -l
Output:
bash
2728
This confirms 2,728 unique items exist in the directories.
Searching Text Patterns with grep
grep finds specific patterns in text. Example: Listing compression-related tools using keyword zip:
ls /bin /usr/bin | sort | uniq | grep zip
Results:
bash
bunzip2
bzip2
gunzip
gzip
unzip
zip
zipcloak
zipgrep
zipinfo
zipnote
zipsplit
Additional grep options:
-i – Ignore case sensitivity.
-v – Show lines that do not match the pattern.
Displaying First or Last Lines with head and tail
head shows first lines; tail shows last lines:
head -n 5 ls-output.txt tail -n 5 ls-output.txt
Useful inside pipelines:
ls /usr/bin | tail -n 5
Example monitoring log files in real-time using tail -f:
tail -f /var/log/messages
To stop monitoring, press Ctrl+C.
Saving Pipeline Output with tee
tee allows saving pipeline data while still passing it forward:
ls /usr/bin | tee ls.txt | grep zip
Now, ls.txt stores the full list, while grep zip extracts relevant results.