Skip to content
Laviyx Learn

Try

Linux and Bash course menu

Linux Pipes and Redirection Explained: |, >, >> and 2>&1

Join commands with pipes, send output to files with > and >>, understand stdin, stdout and stderr, hide errors with /dev/null, use tee, command substitution and xargs.

Beginner6 min readUpdated
On this page

The real power of Linux comes from joining small tools together. Each command does one job, and you connect them.

Three streams#

Every command has three streams:

StreamNumberDefault
Standard input (stdin)0The keyboard
Standard output (stdout)1The screen
Standard error (stderr)2The screen

Redirection sends them somewhere else.

Write output to a file#

> replaces a file, and >> adds to the end:

Terminal
echo "first" > log.txt
echo "second" > log.txt
cat log.txt
echo "third" >> log.txt
cat log.txt
Output
second
second
third

Read input from a file#

< feeds a file to a command's input:

Terminal
sort < log.txt
Output
second
third

Pipes#

| sends the output of one command to the input of the next:

Terminal
ls /etc | wc -l
ls /etc | grep '^host'
Output
234
host.conf
hostname
hosts
hosts.allow
hosts.deny

You can keep adding steps. This shows the three largest entries in /usr/bin:

Terminal
ls -lS /usr/bin | tail -n +2 | head -n 3 | awk '{print $5, $9}'
Output
tail: error writing 'standard output': Broken pipe
98450160 kubectl-convert
93831120 kubectl
83666424 dockerd
ls: write error: Broken pipe

Errors are separate#

Error messages use stderr, so > does not capture them:

Terminal
ls /etc/hostname /nothing > out.txt
echo "--- out.txt:"
cat out.txt
Output
ls: cannot access '/nothing': No such file or directory
--- out.txt:
/etc/hostname

Redirect errors with 2>:

Terminal
ls /etc/hostname /nothing > out.txt 2> err.txt
cat err.txt
Output
ls: cannot access '/nothing': No such file or directory

Send both to the same place with 2>&1, which means "send stream 2 to wherever stream 1 is going":

Terminal
ls /etc/hostname /nothing > all.txt 2>&1
wc -l all.txt
Output
2 all.txt

The order matters: 2>&1 must come after > all.txt.

Throw output away#

/dev/null is a special file that discards everything:

Terminal
ls /nothing 2> /dev/null
echo "Done, and no error shown"
Output
Done, and no error shown

This is common in scripts and cron jobs.

tee: see it and save it#

tee writes to a file and to the screen at the same time:

Terminal
echo "Build finished" | tee build.log
cat build.log
Output
Build finished
Build finished

To write to a protected file, use echo text | sudo tee /etc/file, because sudo echo text > /etc/file fails: the redirection is done by your shell, which is not root.

Command substitution#

$(command) runs a command and inserts its output:

Terminal
echo "This folder has $(ls | wc -l) files"
today=$(date +%A)
echo "${#today} letters in the name of today"
Output
This folder has 5 files
8 letters in the name of today

xargs#

Some commands take names as arguments, not from a pipe. xargs turns input lines into arguments:

Terminal
touch a.tmp b.tmp
ls *.tmp | xargs rm
ls *.tmp 2> /dev/null | wc -l
Output
0

Common mistakes#

Practice#

Practice exercise

Save the names of the files in /etc that end in .conf to conf.txt, hiding any errors, and print how many lines the file has.

Show solution
Terminal
ls -d /etc/*.conf 2> /dev/null > conf.txt
wc -l < conf.txt
Output
34

Using < makes wc print only the number, without the file name.

Key takeaway#

Next: Searching Text with grep.

Finished this lesson?