Skip to content

stdin, stdout, stderr, and pipes

Kenny Yu edited this page Sep 25, 2013 · 7 revisions

So what happens when we run a command?

Each command gets associated with 3 streams called stdin, stdout, and stderr.

  • stdin is a stream that represents input into a program (e.g. when a program prompts the user to enter a password).
  • stdout is where all your output goes. If you've programmed in C, think printf. If you've programmed in Java, think System.out.print. If you've programmed in Python, think print.
  • stderr is another output channel, usually meant for printing debugging information and errors.

Suppose we ran the command:

echo foo

The output of this will be foo. Here's a diagram of what's going on:

echo

The echo command took the input from the arguments foo on the command line (NOT from stdin), and then dumped the output to stdout.

Redirecting

Redirecting output

Suppose now we ran the command:

echo foo > temp.txt
ls

This should have created a new file temp.txt. To see the contents: cat temp.txt. What just happened? What does the > do?

echo out

We redirected the output of echo away from the console and into a file called temp.txt. To append to an existing file, we can use >>:

echo " bar" >> temp.txt
cat temp.txt

Feeding input

Now let's run this command:

wc -w < temp.txt

You should get this output:

      2

The wc is a command that allows you to count things. The -w tells wc to count the number of words. The < told wc to feed its input from temp.txt, essentially making temp.txt the stdin of wc:

wc input

Pipes

A natural question to ask now is: Can we feed the output of one program as input into another? And the answer is yes! We do this using something called a pipe. Run this command:

echo "foo bar baz" | wc -w

You should get 3 as your output. The | character tells your terminal to feed the stdout of the echo command as stdin into the wc command:

pipe

Using pipes, we can chain together many small simple programs together to do very powerful things (like our scraper example)!

Multiple commands, Variables

In addition to chaining commands together with pipes, you can also run a sequence of commands, like so:

mkdir foo; touch foo/file.txt

In this case, we make a directory called foo, and then create a file file.txt in the foo directory. The ; character tells the terminal to run the first command, then separately run the second command. You are not limited to just two commands--you can put any number of commands together by placing a ; between the commands.

Lastly, you can save the output of a command in a variable, and then use that variable sometime later within the same sequence of commands.

myvar="foo"; echo $myvar | tr '[:lower:]' '[:upper:]'

Let's break this sequence of commands down:

  1. First, we assign the variable myvar to have the value of the string foo. Note that there CANNOT be a space between myvar, the = sign, and the value you want the variable to be.

  2. Next, we echo the value of the myvar character. To get the value of a variable, we prefix the variable name with the $ character.

  3. We pipe the output of the echo command into tr '[:lower:]' '[:upper:]', which translates all lower case characters into upper characters, giving us FOO. (tr is a command that allows you to translate characters).

If you wanted to save the output of a command into a variable, use the following syntax: myvar=$(...command(s) you want to run...). Example:

bar=$(echo "Kenny"); echo "Hello $bar"

That should output Hello Kenny.

Finish the rest of bootcamp

See the main page here.