|

Linux CLI 11๐Ÿง Input/Output and redirection

Every command in Linux works with three standard streams โ€” and you can redirect them to files, other commands, or the void. This is one of the most powerful concepts in the shell.


The Three Standard Streams

Every process on Linux has three standard I/O streams:

StreamNameDefault Source/DestinationFile Descriptor
stdinStandard InputKeyboard0
stdoutStandard OutputTerminal1
stderrStandard ErrorTerminal2

Visual:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              Program                  โ”‚
โ”‚                                       โ”‚
โ”‚  stdin (0)  โ”€โ”€โ†’  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”‚
โ”‚  Keyboard        โ”‚  Process โ”‚          โ”‚
โ”‚                  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜          โ”‚
โ”‚                       โ”‚               โ”‚
โ”‚         stdout (1) โ†โ”€โ”€โ”ค               โ”‚
โ”‚         stderr (2) โ†โ”€โ”€โ”˜               โ”‚
โ”‚              โ”‚                        โ”‚
โ”‚              โ–ผ                        โ”‚
โ”‚           Terminal                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key points:

  • stdin โ€” where the program reads input (usually the keyboard)
  • stdout โ€” where the program writes regular output (usually the terminal)
  • stderr โ€” where the program writes errors (usually the terminal)
  • Each stream has a file descriptor (a number the kernel uses)
  • stdin = 0, stdout = 1, stderr = 2

Basic Redirection: stdout

echo "I am Kronos" > output.txt

This redirects the stdout of echo to the file output.txt โ€” overwriting anything that was there.

What happens:

  • Without >: output goes to the terminal
  • With >: output goes to a file (terminal shows nothing)
  • The file is created if it doesn’t exist
  • The file is overwritten if it does exist

Examples:

$ echo "Hello" > file.txt
$ cat file.txt
Hello

$ echo "World" > file.txt    # Overwrites!
$ cat file.txt
World

Redirection Operators

Linux has several operators to redirect the standard streams:

OperatorDescriptionExample
>Redirect stdout to a file (overwrite)echo "Hi" > file.txt
>>Redirect stdout to a file (append)echo "Hi" >> file.txt
<Redirect stdin from a filesort < input.txt
2>Redirect stderr to a filels bad 2> error.txt
2>>Redirect stderr (append)ls bad 2>> error.txt
&>Redirect both stdout and stderr to a filecmd &> all.txt
&>>Redirect both (append)cmd &>> all.txt
2>&1Redirect stderr to where stdout is goingcmd > out.txt 2>&1
1>Explicitly redirect stdout (same as >)cmd 1> out.txt

The >> Operator โ€” Append

echo "My son is Zeus" >> output.txt
cat output.txt

Redirects stdout to a file but appends instead of overwriting.

Comparison:

# > overwrites
$ echo "Line 1" > file.txt
$ echo "Line 2" > file.txt
$ cat file.txt
Line 2

# >> appends
$ echo "Line 1" > file.txt
$ echo "Line 2" >> file.txt
$ cat file.txt
Line 1
Line 2

Visual:

> :  [old content] โ”€โ”€โ†’ [new content]      (old erased)
>> : [old content] โ”€โ”€โ†’ [old content + new] (old kept)

When to use >>:

  • Adding to log files
  • Building up a file incrementally
  • Preserving previous data

The < Operator โ€” Redirect stdin

sort < output.txt

Redirects stdin from a file โ€” the command reads from the file instead of the keyboard.

Example:

# Without redirect โ€” sort waits for keyboard input
$ sort
banana
apple
cherry
# Press Ctrl+D to finish
apple
banana
cherry

# With redirect โ€” reads from file
$ sort < fruits.txt
apple
banana
cherry

Common use cases:

sort < data.txt          # Sort a file
wc -l < data.txt         # Count lines
grep "error" < log.txt   # Search a file

Redirecting stderr (2>)

ls out.txt
ls out.txt 2> error.txt
cat error.txt

Why separate stdout and stderr?

  • Regular output and error messages are different things
  • Sometimes you want to save only errors
  • Or hide errors while showing output

Example:

# ls out.txt โ€” file doesn't exist
$ ls out.txt
ls: cannot access 'out.txt': No such file or directory

# Redirect the error to a file
$ ls out.txt 2> error.txt
# (no output on terminal)

$ cat error.txt
ls: cannot access 'out.txt': No such file or directory

File descriptors in the command:

SyntaxMeaning
2>Redirect stderr (fd 2) to a file
1>Redirect stdout (fd 1) to a file
0<Redirect stdin (fd 0) from a file

Redirecting stdout and stderr

To Different Files

ls out.txt output.txt > lslog.txt 2> error.txt
  • stdout โ†’ lslog.txt
  • stderr โ†’ error.txt

Example:

$ ls existing.txt missing.txt > success.txt 2> errors.txt

$ cat success.txt
existing.txt

$ cat errors.txt
ls: cannot access 'missing.txt': No such file or directory

To the Same File

ls out.txt &> log.txt
  • Both stdout and stderr โ†’ log.txt

Equivalent forms:

# Modern (bash 4+)
cmd &> file.txt

# Traditional (POSIX-compatible)
cmd > file.txt 2>&1

Note: The order matters! 2>&1 must come after >.

cmd > file.txt 2>&1    # โœ… Both go to file.txt
cmd 2>&1 > file.txt    # โŒ stderr goes to terminal, stdout to file

Why? 2>&1 means “make fd 2 point where fd 1 currently points.” If > hasn’t redirected fd 1 yet, fd 2 goes to the terminal.


The /dev/null โ€” The Void

ls d1 1> /dev/null
ls d1 2> /dev/null

/dev/null is a special file that accepts input and does nothing with it โ€” the black hole of Linux.

CommandEffect
cmd > /dev/nullDiscard stdout
cmd 2> /dev/nullDiscard stderr
cmd &> /dev/nullDiscard everything

Examples:

# Hide stdout, show stderr
$ ls existing.txt missing.txt > /dev/null
ls: cannot access 'missing.txt': No such file or directory

# Hide stderr, show stdout
$ ls existing.txt missing.txt 2> /dev/null
existing.txt

# Hide everything
$ ls existing.txt missing.txt &> /dev/null
# (no output)

# Check if a command succeeds silently
$ if ls /nonexistent &> /dev/null; then
    echo "exists"
else
    echo "not found"
fi

Why it’s useful:

  • Testing โ€” run commands without noise
  • Cron jobs โ€” prevent email spam from output
  • Scripts โ€” hide messages you don’t need
  • Silencing errors โ€” hide expected errors

Complete Example Session

# ============================================
# PART 1: REDIRECT STDOUT
# ============================================

$ echo "I am Kronos" > output.txt
$ cat output.txt
I am Kronos

# Overwrite
$ echo "I am Zeus" > output.txt
$ cat output.txt
I am Zeus

# ============================================
# PART 2: APPEND WITH >>
# ============================================

$ echo "My son is Zeus" >> output.txt
$ cat output.txt
I am Zeus
My son is Zeus

$ echo "My wife is Hera" >> output.txt
$ cat output.txt
I am Zeus
My son is Zeus
My wife is Hera

# ============================================
# PART 3: REDIRECT STDIN WITH <
# ============================================

$ cat > fruits.txt
banana
apple
cherry
# Press Ctrl+D

$ sort < fruits.txt
apple
banana
cherry

# ============================================
# PART 4: REDIRECT STDERR WITH 2>
# ============================================

$ ls out.txt
ls: cannot access 'out.txt': No such file or directory

$ ls out.txt 2> error.txt
$ cat error.txt
ls: cannot access 'out.txt': No such file or directory

# ============================================
# PART 5: REDIRECT BOTH STREAMS
# ============================================

# To different files
$ ls output.txt missing.txt > success.txt 2> errors.txt
$ cat success.txt
output.txt
$ cat errors.txt
ls: cannot access 'missing.txt': No such file or directory

# To the same file
$ ls output.txt missing.txt &> combined.txt
$ cat combined.txt
ls: cannot access 'missing.txt': No such file or directory
output.txt

# Traditional syntax
$ ls output.txt missing.txt > combined.txt 2>&1

# ============================================
# PART 6: /dev/null
# ============================================

# Hide stdout
$ ls output.txt missing.txt > /dev/null
ls: cannot access 'missing.txt': No such file or directory

# Hide stderr
$ ls output.txt missing.txt 2> /dev/null
output.txt

# Hide everything
$ ls output.txt missing.txt &> /dev/null
# (no output)

# ============================================
# PART 7: PRACTICAL EXAMPLES
# ============================================

# Log output of a script
$ ./backup.sh > backup.log 2>&1

# Save errors separately
$ ./backup.sh > backup.log 2> backup-errors.log

# Discard output but keep errors
$ ./quiet.sh > /dev/null

# Silent check
$ if ping -c 1 google.com &> /dev/null; then
    echo "Online"
else
    echo "Offline"
fi

# Redirect output of multiple commands
$ { echo "Line 1"; echo "Line 2"; } > multi.txt
$ cat multi.txt
Line 1
Line 2

# Redirect with tee (view AND save)
$ ls | tee ls-output.txt
# Shows output AND saves to file

Quick Reference

Redirection Operators

OperatorDescription
>Redirect stdout (overwrite)
>>Redirect stdout (append)
<Redirect stdin from file
2>Redirect stderr (overwrite)
2>>Redirect stderr (append)
&>Redirect both stdout + stderr (overwrite)
&>>Redirect both (append)
2>&1Point stderr to where stdout goes
> /dev/nullDiscard stdout
2> /dev/nullDiscard stderr
&> /dev/nullDiscard everything

File Descriptors

FDNameDefault
0stdinKeyboard
1stdoutTerminal
2stderrTerminal

/dev/null

AspectDescription
PurposeDiscards everything written to it
Use caseSilencing output/errors
TypeSpecial character device
AlsoReading from it returns EOF immediately

Best Practices

โœ… Do This:

# Use >> for logs
echo "$(date): backup started" >> backup.log

# Separate errors from output
./script.sh > output.log 2> errors.log

# Combine when debugging
./script.sh > all.log 2>&1

# Order matters with 2>&1
cmd > file 2>&1         # โœ… Both to file
cmd 2>&1 > file         # โŒ Wrong order

# Use /dev/null to silence
cron-job &> /dev/null

# Test with tee to see AND save
long-command | tee output.txt

# Check exit codes even with redirection
if cmd > /dev/null 2>&1; then
    echo "success"
fi

โŒ Don’t Do This:

# Don't overwrite important files with >
cat important.log > important.log   # โŒ Erases file!
cat important.log >> important.log  # โœ… Appends

# Don't redirect stderr without redirecting stdout
cmd 2> errors.txt                   # โœ… stderr saved, stdout shown
cmd > output.txt                    # โœ… stdout saved, stderr shown
cmd 2> errors.txt > output.txt      # โœ… Both saved separately

# Don't use > when you want to keep old content
echo "new log entry" > log.txt      # โŒ Overwrites whole log
echo "new log entry" >> log.txt     # โœ… Appends to log

# Don't forget the order with 2>&1
cmd 2>&1 > file.txt                 # โŒ stderr goes to terminal!
cmd > file.txt 2>&1                 # โœ… Correct

# Don't redirect to /dev/null when debugging
./script.sh &> /dev/null            # โŒ You see nothing!
./script.sh                         # โœ… Debug normally

Common Pitfalls

PitfallProblemSolution
> overwritesLoses old dataUse >> for appending
2>&1 orderstderr not redirectedPut 2>&1 after >
Redirection on nonexistent dirErrorCreate dir first
/dev/null on important dataData lostUse tee to save
Confusing stderr and stdoutWrong file gets errorUse 2> for stderr
Bash-specific &> in scriptsNot portableUse > file 2>&1

Real-World Examples

1. Logging Script Output

#!/bin/bash
# Run backup, save both stdout and stderr to log
./backup.sh >> /var/log/backup.log 2>&1

# Save output and errors separately
./backup.sh > backup-success.log 2> backup-error.log

2. Silent Cron Jobs

# In crontab โ€” run every hour, no email
0 * * * * /usr/local/bin/cleanup.sh &> /dev/null

3. Test If Command Exists

if command -v git &> /dev/null; then
    echo "Git is installed"
else
    echo "Please install Git"
fi

4. Suppress Expected Errors

# Find files, ignore permission errors
find / -name "*.conf" 2> /dev/null

# List directories, ignore "not found" errors
ls -d */ 2> /dev/null

5. Build Incremental Log

#!/bin/bash
LOG="build.log"

echo "===== Build started $(date) =====" >> $LOG
make >> $LOG 2>&1
echo "===== Build finished $(date) =====" >> $LOG

6. View and Save with tee

# See output AND save to file
ls -la | tee directory-listing.txt

# Append instead of overwrite
ls -la | tee -a directory-listing.txt

# Save and see, but suppress errors
command 2> /dev/null | tee output.txt

7. Redirect Only Errors

# Run script, show output, save errors
./script.sh 2> errors.log

# Run script, discard output, see errors
./script.sh > /dev/null

Visual: Redirection Flow

BEFORE (no redirection):
   Command  โ”€โ”€stdoutโ”€โ”€โ†’  Terminal
            โ”€โ”€stderrโ”€โ”€โ†’  Terminal

AFTER (echo "Hi" > file.txt):
   Command  โ”€โ”€stdoutโ”€โ”€โ†’  file.txt
            โ”€โ”€stderrโ”€โ”€โ†’  Terminal

AFTER (cmd &> file.txt):
   Command  โ”€โ”€stdoutโ”€โ”€โ†’  file.txt
            โ”€โ”€stderrโ”€โ”€โ†’  file.txt

AFTER (cmd 2> /dev/null):
   Command  โ”€โ”€stdoutโ”€โ”€โ†’  Terminal
            โ”€โ”€stderrโ”€โ”€โ†’  /dev/null (discarded)

Summary

ConceptDescription
stdin (0)Input, usually keyboard
stdout (1)Output, usually terminal
stderr (2)Errors, usually terminal
>Redirect stdout, overwrite
>>Redirect stdout, append
<Redirect stdin from file
2>Redirect stderr
&>Redirect both
2>&1Point stderr to stdout
/dev/nullDiscards everything

Key takeaways:

  • Every command has three streams: stdin (0), stdout (1), stderr (2)
  • > overwrites, >> appends
  • 2> redirects errors separately from output
  • &> or > file 2>&1 redirects both streams
  • /dev/null is the void โ€” use it to silence output or errors
  • Order matters โ€” 2>&1 must come after > to work correctly
  • Use tee when you want to see AND save output

Remember: Redirection is what makes the shell composable. It lets you chain commands, save output, discard noise, and control exactly where every byte goes. Master >, >>, 2>, and /dev/null, and you’ll write far more powerful scripts. The three streams are the plumbing of the command line โ€” once you understand them, everything clicks!


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!