Standard I/O & Pipes

Standard Streams

Of course, real factories don't have magic pipes that can transport everything, and in the physical world there's no such thing as a universal input/output connector. It turns out, however, that the shell does have those things, or something pretty close to them:

standard input or stdin

accepts stuff

file descriptor 0

standard output or stdout

spits stuff out

file descriptor 1

standard error or stderr

spits out error messages (usually to the terminal; more about that in a bit)

file descriptor 2

pipes

move stuff between streams

Let's back up a bit. Imagine that a command like head or tail is a machine that takes input in one side and spits part of it out the other. In many of the examples we've see so far, you specify the input by giving the command an argument naming a file to use, like tail /usr/share/dict/words, and the output appears in your terminal. In other cases, a program runs interactively and accepts input directly from the terminal itself - that is, from what you type on your keyboard.

The location of the dictionary may have changed, try `/usr/share/dict/wamerican` instead! or `ls /usr/share/dict` to see what's available

What you see in your terminal is like the stuff coming out one end of a machine, or like an open tap spilling water on the ground. You don't have to let it spill out directly into the terminal, though - the machine has a universal output connector of sorts, in the form of stdout, and you can connect it to the stdin of other machines with a pipe.

Building a Simple Pipeline

Have a look on your keyboard and see if you can find this little critter: |. It's often (though not always) located on the same key as the backslash (\). Let's try it on something simple.

Suppose you wanted to see the end of the word list, but starting from the last word and working backwards. The sort utility will be helpful here, especially since it optionally takes the -r argument to reverse its output.

This is called a pipeline, and it's one of the fundamental building blocks of the modern shell. Most traditional shell utilities will accept standard input and produce standard output.

Pipelines are often simple affairs joining a few basic commands, but they can also be used to express complicated tasks combining many different operations. Here's a slightly more complicated pipeline to have an ASCII-art cow say the usernames of people who have logged into a server I run, starting with most recent login:

Download: file
lastlog | egrep -v 'Never|Username|root' | awk '{ print $1; }' | xargs cowsay

Next, let's talk about what to do if you want to stash standard output somewhere.

This guide was first published on Feb 17, 2015. It was last updated on Feb 17, 2015. This page (Standard I/O & Pipes) was last updated on May 23, 2019.