Understanding Linux shell commands and I/O redirection is fundamental to becoming proficient with the command line. This comprehensive guide introduces you to shell command structure and teaches you how to redirect input and output to make your workflow more efficient.
🎯 What You'll Learn: In this hands-on tutorial, you'll discover:
- The anatomy of a Linux shell command
- How to redirect command output to files using
>
and>>
- How to use input redirection with
<
- How to chain commands together using pipes
|
- Practical examples with real-world applications
- The difference between overwriting and appending to files
🚀 Understanding Shell Command Structure
Every Linux command follows a simple, predictable structure that makes it easy to understand and use once you grasp the basics.
The Basic Anatomy
command [options] [arguments]
Let's break this down:
- command: The program or utility you want to execute (e.g.,
ls
,pwd
,date
) - options: Flags that modify how the command behaves, usually prefixed with
-
or--
- arguments: The data or files the command operates on
💡 Example: In the command ls -l /home
, ls
is the command, -l
is the option (long format), and /home
is the argument (the directory to list).
Real-World Example
Let's see this structure in action:
ls -l /home
Output:
total 8
drwx------. 26 centos9 centos9 4096 Oct 1 12:43 centos9
drwx------. 3 labuser labuser 78 Jul 24 20:30 labuser
drwx------. 14 labuser labuser 4096 Jul 24 19:37 labuser1
What's happening here:
ls
is the command that lists directory contents-l
is an option that displays the long format with detailed information/home
is the argument specifying which directory to list
Column | Meaning | Example |
---|---|---|
Permissions | Read, write, execute permissions | drwx------ |
Links | Number of hard links | 26 |
Owner | User who owns the file | centos9 |
Group | Group that owns the file | centos9 |
Size | File size in bytes | 4096 |
Date/Time | Last modification time | Oct 1 12:43 |
Name | File or directory name | centos9 |
Combining Multiple Options
You can combine multiple options in a single command:
ls -lh
Output:
total 5.8M
drwxr-xr-x. 11 centos9 centos9 4.0K Sep 22 00:53 blog
-rw-r--r--. 1 centos9 centos9 109 Sep 15 00:14 claude-api
drwxr-xr-x. 2 centos9 centos9 136 Oct 1 01:33 Desktop
drwxr-xr-x. 2 centos9 centos9 6 Jul 20 15:36 Documents
drwxr-xr-x. 2 centos9 centos9 119 Sep 24 23:07 Downloads
-rw-r--r--. 1 centos9 centos9 1.1K Oct 1 13:11 file_list.txt
drwxr-xr-x. 2 centos9 centos9 6 Jul 20 15:36 Music
-rw-r--r--. 1 centos9 centos9 18 Oct 1 13:14 names.txt
What the options do:
-l
: Long format (detailed information)-h
: Human-readable sizes (shows 5.8M instead of 6044864 bytes)
Notice how file sizes are now displayed in a more readable format: 4.0K
(kilobytes), 1.1K
, 5.8M
(megabytes), instead of raw byte counts.
✅ Pro Tip: The -h
option is incredibly useful when checking disk usage. It makes sizes much easier to understand at a glance!
📤 Output Redirection: Saving Command Output
Output redirection allows you to save the output of a command to a file instead of displaying it on the screen. This is incredibly useful for logging, data processing, and creating reports.
The >
Operator (Overwrite)
The >
operator redirects output to a file and overwrites any existing content.
ls -l > file_list.txt
What happens:
- The
ls -l
command generates a long listing of files - Instead of printing to the terminal, the output is saved to
file_list.txt
- If
file_list.txt
already exists, its contents are completely replaced
Let's verify the contents:
cat file_list.txt
Output:
total 5920
drwxr-xr-x. 11 centos9 centos9 4096 Sep 22 00:53 blog
-rw-r--r--. 1 centos9 centos9 109 Sep 15 00:14 claude-api
drwxr-xr-x. 2 centos9 centos9 136 Oct 1 01:33 Desktop
drwxr-xr-x. 2 centos9 centos9 6 Jul 20 15:36 Documents
drwxr-xr-x. 2 centos9 centos9 119 Sep 24 23:07 Downloads
-rw-r--r--. 1 centos9 centos9 0 Oct 1 13:11 file_list.txt
drwxr-xr-x. 2 centos9 centos9 6 Jul 20 15:36 Music
⚠️ Important: The >
operator will overwrite the entire file. Any previous content will be lost. Use >>
if you want to preserve existing content.
Real-World Example: Creating a File
Let's create a file with some content:
echo "Hello, RedHat Openshift!" > greeting.txt
What happens:
- The
echo
command outputs text >
redirects that text togreeting.txt
- A new file is created with the content
Verify the content:
cat greeting.txt
Output:
Hello, RedHat Openshift!
Now let's overwrite it:
echo "New content replaces old" > greeting.txt
cat greeting.txt
Output:
New content replaces old
See how the original content is completely gone? That's the >
operator in action.
The >>
Operator (Append)
The >>
operator appends output to a file without erasing existing content.
echo "Additional line" >> greeting.txt
cat greeting.txt
Output:
New content replaces old
Additional line
Let's add more lines:
echo "Line 3" >> greeting.txt
echo "Line 4" >> greeting.txt
cat greeting.txt
Output:
New content replaces old
Additional line
Line 3
Line 4
✅ Use Case: The >>
operator is perfect for logging. You can continuously append log entries without losing historical data.
Appending Timestamps to Logs
Here's a practical example of building a log file:
date >> file_list.txt
cat file_list.txt
Output:
total 5920
drwxr-xr-x. 11 centos9 centos9 4096 Sep 22 00:53 blog
-rw-r--r--. 1 centos9 centos9 109 Sep 15 00:14 claude-api
drwxr-xr-x. 2 centos9 centos9 136 Oct 1 01:33 Desktop
[... more lines ...]
Wed Oct 1 01:11:37 PM PKT 2025
The timestamp is added to the end of the file, preserving all previous content.
📥 Input Redirection: Reading from Files
Input redirection allows you to feed file contents as input to a command, rather than typing the data manually.
The <
Operator
The <
operator reads input from a file instead of the keyboard.
Let's create a file with some names:
echo -e "Bob\nAlice\nCharlie" > names.txt
cat names.txt
Output:
Bob
Alice
Charlie
Understanding the command:
echo -e
enables interpretation of backslash escapes\n
represents a newline character- This creates three lines of text in one command
Now let's sort the names using input redirection:
sort < names.txt
Output:
Alice
Bob
Charlie
What happens:
- The
sort
command reads fromnames.txt
(via<
) - It alphabetically sorts the lines
- The sorted output is displayed on the screen
💡 Note: The original file names.txt
remains unchanged. The sort
command only processes the input and displays results; it doesn't modify the source file.
Verify the original file is unchanged:
cat names.txt
Output:
Bob
Alice
Charlie
Still in the original order!
🔗 Pipes: Chaining Commands Together
Pipes (|
) connect the output of one command to the input of another, allowing you to build powerful command chains.
Basic Pipe Syntax
command1 | command2
The output of command1
becomes the input for command2
.
Example 1: Filtering Output
Let's find all .txt
files in the current directory:
ls -l | grep .txt
Output:
-rw-r--r--. 1 centos9 centos9 1077 Oct 1 13:11 file_list.txt
-rw-r--r--. 1 centos9 centos9 18 Oct 1 13:14 names.txt
-rw-r--r--. 1 centos9 centos9 6044864 Jul 31 15:41 test.txt
What happens:
ls -l
generates a long listing of all files|
pipes that output togrep
grep .txt
filters and shows only lines containing.txt
Example 2: Counting Lines
Let's count how many lines are in a file:
cat greeting.txt | wc -l
Output:
4
Breaking it down:
cat greeting.txt
outputs the file contents (4 lines)|
pipes the output towc
wc -l
counts the number of lines (-l
flag)- Result: 4 lines
Example 3: Processing Command Output
Let's count how many Podman processes are running:
ps aux | grep podman | wc -l
Output:
1
The pipeline:
ps aux
lists all running processes| grep podman
filters for lines containing "podman"| wc -l
counts the matching lines
Example 4: Sorting and Saving
Let's sort the names and save the result:
cat greeting.txt | sort
Output:
Additional line
Line 3
Line 4
New content replaces old
Now save the sorted output:
cat greeting.txt | sort > sorted_greeting.txt
cat sorted_greeting.txt
Output:
Additional line
Line 3
Line 4
New content replaces old
Verify the original is unchanged:
cat greeting.txt
Output:
New content replaces old
Additional line
Line 3
Line 4
✅ Key Concept: Pipes and redirection can be combined! You can chain multiple commands with pipes and then redirect the final output to a file.
🎯 Practical Examples
Let's explore some real-world scenarios where I/O redirection shines.
Example 1: Filtering Container Images
List all Podman images:
podman images
Output:
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/python 3.9-alpine 73999da24fd3 2 months ago 52.3 MB
docker.io/library/alpine latest 9234e8fb04c4 2 months ago 8.61 MB
docker.io/library/nginx latest 22bd15417453 2 months ago 196 MB
docker.io/library/ubuntu latest 65ae7a6f3544 2 months ago 80.6 MB
docker.io/library/redis alpine a87c94cbea0b 2 months ago 61.3 MB
docker.io/library/nginx alpine d6adbc7fd47e 3 months ago 53.9 MB
docker.io/library/postgres 13-alpine 920d587d8d93 3 months ago 271 MB
docker.io/library/postgres 15-alpine 546a2cf48182 3 months ago 276 MB
docker.io/library/python 3.9 88c1183c92cf 3 months ago 1.02 GB
docker.io/library/python 3.9-alpine 8cccaac7ca7e 3 months ago 52.3 MB
Filter out images with <none>
tags:
podman images | grep -v "<none>"
Output:
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/python 3.9-alpine 73999da24fd3 2 months ago 52.3 MB
docker.io/library/alpine latest 9234e8fb04c4 2 months ago 8.61 MB
docker.io/library/nginx latest 22bd15417453 2 months ago 196 MB
docker.io/library/ubuntu latest 65ae7a6f3544 2 months ago 80.6 MB
docker.io/library/redis alpine a87c94cbea0b 2 months ago 61.3 MB
[... and so on ...]
What -v
does:
grep -v
inverts the match- It shows lines that do NOT contain
<none>
- Useful for filtering out untagged/dangling images
Example 2: System Information Report
Create a comprehensive system report:
{
echo "=== System Report ==="
date
echo "=== Memory ==="
free -h
echo "=== Disk Usage ==="
df -h
} > system_report.txt
View the report:
cat system_report.txt
Output:
=== System Report ===
Wed Oct 1 01:37:33 PM PKT 2025
=== Memory ===
total used free shared buff/cache available
Mem: 7.5Gi 1.9Gi 4.2Gi 127Mi 1.8Gi 5.6Gi
Swap: 7.9Gi 0B 7.9Gi
=== Disk Usage ===
Filesystem Size Used Avail Use% Mounted on
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 3.8G 71M 3.7G 2% /dev/shm
tmpfs 1.6G 18M 1.5G 2% /run
/dev/mapper/cs_vbox-root 62G 11G 52G 17% /
/dev/sda1 960M 609M 352M 64% /boot
/dev/mapper/cs_vbox-home 30G 8.8G 22G 30% /home
Understanding the grouped commands:
{ }
groups multiple commands- Each command's output is combined
>
redirects all output to one file- Creates a nicely formatted report with sections
✅ Pro Tip: This technique is perfect for scheduled system monitoring. You can create automated reports that track system health over time.
Example 3: Container Inventory Report
Create a container status report:
{
echo "=== Container Images ==="
podman images
echo "=== Running Containers ==="
podman ps
} > container_report.txt
View the report:
cat container_report.txt
Output:
=== Container Images ===
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/python 3.9-alpine 73999da24fd3 2 months ago 52.3 MB
docker.io/library/alpine latest 9234e8fb04c4 2 months ago 8.61 MB
[... more images ...]
=== Running Containers ===
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
This creates a snapshot of your container environment - useful for documentation and auditing.
📊 Command Reference Tables
Output Redirection Operators
Operator | Name | Function | Example |
---|---|---|---|
> | Output redirect | Overwrite file with output | ls > list.txt |
>> | Append redirect | Append output to file | date >> log.txt |
< | Input redirect | Read input from file | sort < names.txt |
| | Pipe | Connect command outputs | ls | grep txt |
Common Pipe Combinations
Command Chain | Purpose |
---|---|
command | grep pattern | Filter output by pattern |
command | wc -l | Count lines in output |
command | sort | Sort output alphabetically |
command | head -n 10 | Show first 10 lines |
command | tail -n 10 | Show last 10 lines |
command | tee file.txt | Display AND save to file |
🎯 Best Practices
✅ Essential Tips
- Use
>>
for logs: Always append to log files rather than overwriting them - Test before overwriting: Use
cat
orls
to verify file contents before using>
- Combine operators: You can use
<
,>
, and|
together in complex workflows - Verify your output: Always check files after redirection to ensure the operation succeeded
- Use descriptive filenames: Name output files clearly (e.g.,
system_report_2025-10-01.txt
) - Chain commands wisely: Break complex pipes into steps when debugging
- Check file permissions: Ensure you have write permissions before redirecting output
📝 Command Cheat Sheet
Quick reference for basic I/O redirection:
# Output redirection
command > file.txt # Overwrite file with output
command >> file.txt # Append output to file
# Input redirection
command < input.txt # Read input from file
# Pipes
command1 | command2 # Connect commands
command1 | command2 | command3 # Chain multiple commands
# Combined redirection and pipes
command < input.txt | sort > output.txt # Read, process, save
ls -l | grep .txt > text_files.txt # Filter and save
# Useful combinations
ls -l | grep pattern # List and filter
ps aux | grep process # Find processes
cat file | sort # Display and sort
command | wc -l # Count output lines
command | head -n 20 # Show first 20 lines
command | tail -n 20 # Show last 20 lines
command | tee file.txt # Display and save simultaneously
🚀 What's Next?
📚 Continue Learning
In Part 2, we'll cover:
- Error redirection with
2>
- Combining stdout and stderr with
&>
- Using
/dev/null
to discard output - Grouping commands for complex redirections
- Advanced piping techniques
- Practical automation scenarios
Stay tuned for the advanced guide!
🎉 Congratulations! You've mastered the fundamentals of Linux shell commands and I/O redirection. You can now save command output, chain commands together, and build efficient command-line workflows.
What did you think of this guide? Drop your questions or share your favorite I/O redirection tricks in the comments below!
💬 Discussion
I'd love to hear about your experience:
- What commands do you redirect most often?
- Have you built any useful command pipelines?
- What topics would you like covered in Part 2?
- Any challenging scenarios you'd like help with?
Connect with me: