ShareYourGroupShareYourGroupCommands

Linux and Mac commands

Pipes and redirection: join commands together

The idea that makes the command line powerful is simple: small commands that each do one thing, joined so that the output of one becomes the input of the next. This page covers the joining.

Three streams

Every command has three channels.

NameNumberNormally connected to
standard input (stdin)0the keyboard
standard output (stdout)1the screen
standard error (stderr)2the screen

Results go to standard output. Error messages go to standard error, so that they can be separated from results. Redirection reconnects these channels to files or to other commands.

Output into a file: >

Linux or Mac terminal
asha@pc:~/demo$ ls > list.txt
asha@pc:~/demo$ cat list.txt
list.txt
log.txt
marks.csv
notes.txt
old
photos
report.txt

Nothing appeared on screen for the first command, because its output went into the file.

Danger. > empties the file before writing. If the file exists, its old contents are gone, with no question asked. In Bash and Zsh, set -o noclobber makes the shell refuse to overwrite with >.

Adding to a file: >>

Linux or Mac terminal
asha@pc:~/demo$ echo "one more line" >> list.txt
asha@pc:~/demo$ tail -n 2 list.txt
report.txt
one more line

The pipe

The | sign connects the output of the command on its left to the input of the command on its right.

Linux or Mac terminal
asha@pc:~/demo$ ls | wc -l
7

ls produced a list, and wc -l counted its lines. Pipes can be chained as far as you like.

Linux or Mac terminal
asha@pc:~/demo$ cat log.txt | grep ERROR | wc -l
2
asha@pc:~/demo$ sort marks.csv | head -n 3
Asha,78
Kabir,33
Meena,92

Read a pipeline from left to right, as a production line: each command receives, changes and passes on.

A real pipeline

Which kinds of message does the log contain, and how many of each?

Linux or Mac terminal
asha@pc:~/demo$ cut -c7-11 log.txt | sort | uniq -c | sort -rn
      5 INFO 
      2 ERROR
      1 WARN 

Step by step: cut takes characters 7 to 11 of each line, where the level is written. sort puts equal lines together. uniq -c collapses them and counts. The final sort -rn puts the largest count first. Four small commands, no programming.

Build a pipeline one stage at a time, running it after each addition to see what the next command will receive.

Input from a file: <

< connects a file to a command's input.

Linux or Mac terminal
asha@pc:~/demo$ wc -l < notes.txt
3

It is less often needed, since most commands accept a file name directly.

Errors

Error messages travel on stream 2, so > alone does not catch them.

Linux or Mac terminal
asha@pc:~/demo$ ls notes.txt missing.txt > out.txt
ls: cannot access 'missing.txt': No such file or directory
asha@pc:~/demo$ cat out.txt
notes.txt

The result for notes.txt went to the file. The error for the missing file still came to the screen.

WriteTo send
2> errors.txterrors to a file
2>/dev/nullerrors nowhere: discard them
> all.txt 2>&1both results and errors to one file
&> all.txtthe same, in Bash and Zsh
Linux or Mac terminal
asha@pc:~/demo$ ls notes.txt missing.txt > out.txt 2> err.txt
asha@pc:~/demo$ cat err.txt
ls: cannot access 'missing.txt': No such file or directory

/dev/null is a special file that discards whatever is written to it. find / -name hosts 2>/dev/null hides the many "Permission denied" lines.

The order matters in > file 2>&1. It says "send output to the file, then send errors to wherever output now goes". Written the other way round, errors still reach the screen.

tee: see it and save it

tee copies its input both to a file and onward to the screen, like a T-shaped pipe joint.

Linux or Mac terminal
asha@pc:~/demo$ ls | tee names.txt | wc -l
9

tee -a appends. It is also the way to write to a protected file with sudo, since sudo echo text > file fails: the redirection is done by your own shell, not by sudo. echo text | sudo tee file works.

Running commands one after another

FormMeaning
a ; brun a, then b, whatever happens
a && brun b only if a succeeded
a || brun b only if a failed
Linux or Mac terminal
asha@pc:~/demo$ mkdir -p build && echo "folder ready"
folder ready
asha@pc:~/demo$ ls nofile 2>/dev/null || echo "not there"
not there

&& is the safe way to chain steps. cd project && rm -r tmp deletes only if the cd worked. With a semicolon, a failed cd would leave rm running in the wrong folder.

xargs: turn input into arguments

Some commands take names as arguments, not as input. xargs bridges the gap.

Linux or Mac terminal
asha@pc:~/demo$ ls *.txt | xargs wc -l
  1 err.txt
  8 list.txt
  8 log.txt
  9 names.txt
  3 notes.txt
  1 out.txt
  5 report.txt
 35 total

For file names that may contain spaces, use find ... -print0 | xargs -0 ....

Useful commands in pipelines

CommandDoes
sortsort lines
uniqremove repeated neighbouring lines
wc -lcount lines
head, tailfirst or last lines
grepkeep matching lines
cuttake columns
trchange or delete characters

See sort, uniq, wc and cut.

On Windows

The Command Prompt has the same >, >>, <, |, 2> and &&. The commands on either side are different, but the plumbing works the same way.

Examples shown with output were run on 12 November 2026 in a practice folder: Windows commands in cmd.exe on Windows 11, Linux commands with the GNU tools of Git Bash. The folder path and user name were replaced with made-up ones. Commands marked "not run here" are shown as you would type them.

This is an independent learning site. It is not connected with Microsoft, Apple or any Linux distribution. Windows, macOS and other names belong to their owners. Try commands first in a practice folder, never on files you cannot afford to lose.