DEV Community

Cover image for Stupid Short: Bash's |, >, >>, <, 2>>, 2> Operators
Lee
Lee

Posted on

Stupid Short: Bash's |, >, >>, <, 2>>, 2> Operators

This is meant to be a stupid-short introductory and reference guide for quickly understanding these Bash operators: >, 1>, >>, 1>>, <, 2>>, 2>>. This is primarily done with one sentence and an example.

This guide assumes...

  1. ... you are using Bash terminal. (OS is not relevant)
  2. ... you are familiar with CLI usage and navigation.
  3. ... you are familiar with the concepts of Bash program arguments/flags/options.

Contents

Note: For this blog, we will assume we are only writing and reading files.


Mostly-Short Fundamentals

Admittedly, I never bothered to look up what the | > >> and < operators do in Linux until well into my programming career. If you've ever followed GitHub's instructions for adding an SSH key to your account, then you've already used are called Redirect Operators!

Fundamentals of Programs

A program has three input and output streams with their corresponding number. It has a standard input (STDIN)(0), standard output (STDOUT)(1), and standard error (STDERR)(2).

Chart of program I/O streams

Note: My beautiful picture is only showing convention. If you build your own program, you can effectively name streams whatever you'd like and stream to whatever output. You don't know that though. If you do, act like you don't and read on.

Example: Let's take the good ol' ls. When you ls with no error, the input is ./ (Bash assumes empty is current directory), the stdout is the list of directories you then see, and the stderr is nothing (Because there's no error to catch).

Programs stream both stdout and stderr; this is because it's not "stdout or stderr", it's "stdout and stderr". Running ls presentDir notPresentDir, you can see both stdout and stderr.

By default, stdout, stderr, and stdin are all in the terminal. With these redirection operators, we're simply redirecting those streams elsewhere.


Vocab

"program": This is what executables are called in terminal. Every time you cd or ls, you're running a program.
cat: Program that prints the contents of a given file.
wc -w: Program that outputs the count of words in a file.
pbc: My alias for xclip -selection clipboard. For Mac folks, this is the exact same thing as pbcopy.
pbp: My alias for pasting clipboard.


Stupid-Short List

⭐️ The redirect operators have three numbers correlating with the output: 0 = input, 1 = output, 2 = error. If no number is given, this defaults to 1.
⭐️ If the file does not exist, these operators create the file.

> Write stdout to given file.

Sends stdout to a given file, instead of printing in the terminal.

$ ls -1 > list.txt

$ cat list.txt
lubbock.txt
odessa.txt
baird.txt
Enter fullscreen mode Exit fullscreen mode

>> Appends stdout to given file.

Adds stdout to file contents, not replacing file contents.

$ echo "Flamingo" >> favorite-birds.txt

$ cat favorite-birds.txt
Cardinal
Penguin
Flamingo
Enter fullscreen mode Exit fullscreen mode

< Redirects file as stdin

Passes the contents of a file as the stdin.
Example: If we use wc -w book.txt, the program will output the word count and the filename of book.txt (ex: 2394 book.txt).
If we use wc -w < book.txt we are "passing in" the contents of book.txt as the input, therefore wc -w < book.txt would return only the number (2394), as if we typed the whole thing into terminal.

$ wc -w book.txt
2394 book.txt

$ wc -w < book.txt
2394
Enter fullscreen mode Exit fullscreen mode

2>: Redirect stderr to given file.

If there is an error, redirect the stderr to a file instead of printing in terminal.

$ ls cuteDogPics 2> example.txt

$ cat example.txt
ls: cuteDogPics: No such file or directory
Enter fullscreen mode Exit fullscreen mode

2>>: Appends stderr to given file.

Exactly like >> and >, except with stderr.

$ cp ~/Documents/Reports/June2019.xlsx ~/Desktop 2>> ~/error.log

$ cat ~/error.log
cp: /Users/bananabrann/Reports/January2019.xlsx: No such file or directory
cp: /Users/bananabrann/Reports/March2019.xlsx: No such file or directory
cp: /Users/bananabrann/Reports/June2019.xlsx: No such file or directory

Enter fullscreen mode Exit fullscreen mode

|: Use the stdout as stdin for the next program.

Use the stdout of the program left of the | as stdin to the program to the right.

$ ls -1
buffalo-gap.txt
abilene.txt
clyde.txt
lubbock.txt

$ ls -1 | head -2
buffalo-gap.txt
abilene.txt
Enter fullscreen mode Exit fullscreen mode

Able to be daisy-chained

Using the |, we can ultimately chain as many programs as we'd like to achieve the desired result.
In the picture below, we take the stdout of the grep program and send it as the stdin of head and its arguments. We then send that stdout to the stdin of tail, then finally redirect the stdout to guestlist.txt.

Alt text of image


Hope this helped someone, or sparked someone's interest to play around with these operators and research further on their own!

Happy Coding! 🍻

Discussion (15)

Collapse
thorstenhirsch profile image
Thorsten Hirsch

Here's one more I'm using sometimes:

$ call-foo > out_and_err.txt 2>&1

So here I'm redirecting STDERR to the address of STDOUT, which is a file called "out_and_err.txt".

Collapse
fennecdjay profile image
Jérémie Astor

I think that in recent bash and zsh, one can use

call-foo &> out_and_err.txt
Collapse
sinewalker profile image
Mike Lockhart • Edited on

This is my favourite "shut up, I don't want to see any output, even if it fails, just do, or don't do, the thing" shortcut:

call-foo &> /dev/null
Thread Thread
fennecdjay profile image
Jérémie Astor

I think you have a small typo here.
Shouldn't it read

call-foo &> /dev/null
Thread Thread
sinewalker profile image
Mike Lockhart

Thank you, fixed 😁

Thread Thread
fennecdjay profile image
Jérémie Astor

You're welcome.

Collapse
bananabrann profile image
Lee Author • Edited on

I would've done call-foo > out-and-error.txt 2> out-and-error.txt; I've never heard of 2>&1 or &>. Very cool! Thanks for that!

What would be a practical application of print stdout and stderr to the same file?

@fennecdjay
@thorstenhirsch
@sinewalker

Thread Thread
sinewalker profile image
Mike Lockhart

Openssl prints diagnostic info to stderr and certificate info to stdout. If you want them both in the same filter stream, &> is very handy. Or if you want them all in the same single log file

Collapse
masedi profile image
Edi Septriyanto

What's & mean?

Collapse
ismiyati profile image
ismiyati
Collapse
ferricoxide profile image
Thomas H Jones II

Another really useful redirection-related BASHism: <( ):

Useful if, say, you want to check to see if a local file and an S3-hosted file are the same:

$ sha256sum <( aws s3 cp s3://BUKKIT1/file - ) ./file
d20c7a50c3ac734230b08dbe2cb9122634c2dd040eee56ebd8101bef455dbb88 */dev/fd/63
c204dbfa154fc4801bdaac298584815bbd1b4a968a2349dd17f1e7c459904d41 *file
Enter fullscreen mode Exit fullscreen mode

Similarly, can be used for things like diffing two streams:

diff <( aws s3 cp s3://BUKKIT1/file - ) <( aws s3 cp s3://BUKKIT2/file - )
Enter fullscreen mode Exit fullscreen mode
Collapse
moopet profile image
Ben Sinclair

Another one people don't seem to use much is >| which will overwrite a file even if noclobber is on.

Collapse
hinchk profile image
Kasey

Makes truncating a breeze! |> logfile.log

Collapse
yaser profile image
Yaser Al-Najjar

I never looked these up before, though I use most of them almost everyday 😁

Thanks Pierson!

Collapse
bananabrann profile image
Lee Author

Haha, I was in the same boat!