-
Notifications
You must be signed in to change notification settings - Fork 4
stdin, stdout, stderr, and pipes
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, thinkprintf
. If you've programmed in Java, thinkSystem.out.print
. If you've programmed in Python, thinkprint
. -
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:
The echo
command took the input from the arguments foo
on the command line (NOT from stdin), and then dumped the output to stdout
.
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?
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
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:
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:
Using pipes, we can chain together many small simple programs together to do very powerful things (like our scraper example)!
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:
-
First, we assign the variable
myvar
to have the value of the stringfoo
. Note that there CANNOT be a space betweenmyvar
, the=
sign, and the value you want the variable to be. -
Next, we
echo
the value of themyvar
character. To get the value of a variable, we prefix the variable name with the$
character. -
We pipe the output of the
echo
command intotr '[:lower:]' '[:upper:]'
, which translates all lower case characters into upper characters, giving usFOO
. (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
.
See the main page here.