Redirecting standard input and output – 2.0
Many CLI programs use a feature called input/output redirection. This powerful feature allows you to “glue” simple commands together in order to construct more complex commands.
< Standard output >
Many Linux commands print their output to screen. For example,
ls does this when it lists the contents of a directory: you see the output, the directory listing, on your screen.
cat does the same: it concatenates a file and sends the results to your screen, and thus you can see the file’s contents. But the screen isn’t the only place where the commands can print their output because you can redirect the output of several commands to files, devices, and even to the input of other commands.
The CLI programs that display their results do so usually by sending the results to standard output, or stdout for short. By default, standard output directs its contents to the screen, as you’ve seen with the
catcommands. But if you want to direct the output to somewhere else, you can use the > character. For example, to redirect the output to a file, you can use the > character like this:
$ ls > dir_listing.txt
The above redirects the output of the
ls command to a file called
dir_listing.txt. Because the output is redirected to a file, you don’t see any results of
ls on your screen.
Each time you repeat the above command, the file
dir_listing.txt is overwritten with the results of the
ls command. If you want to append the new results to the file instead of rewriting it, you can use >> instead:
$ ls >> dir_listing.txt
Each time you repeat the above command, the new output of
ls is added at the end of the
dir_listing.txt file instead of overwriting the file.
The following adds the contents of
File1 at the end of
$ cat File1 >> File2
Like I told you before, files aren’t the only places where you can redirect the standard output. You can redirect it to devices, too:
$ cat sound.wav > /dev/audio
As you saw, in the above example the
cat command concatenates a file named
sound.wav and the results are sent to a device called
/dev/audio. What’s the fun here, then?
/dev/audio is the audio device, and when you send there the contents of a sound file, that file is played. So if your sound is properly configured, the above command plays the file
< Standard input >
Many commands accept input from standard input, or stdin for short. By default, standard input reads information from your keyboard, but just like standard output, it can be redirected. Let’s examine this a bit.
We can use a little program called
tac when experimenting.
tac reads standard input and then displays it to you with all the lines reversed (compare
cat). You can first see how
tac works when it reads the input from your keyboard. Just give the command
tac and type a few lines of text, using Enter for starting new lines. Then press Ctrl+D when you’re done. See how
tac then displays the text with all the lines reversed?
When used like this,
tac is pretty useless. But you can redirect the input so that
tac gets it from a file instead of the keyboard. You can do it with the < character, like this:
$ tac < list_az.txt
In the example above
tac reads the input from a file called
list_az.txt and sends the results to standard output. Because the output isn’t redirected anywhere, it’s displayed on your screen, where you see the lines of
lines_az.txt in reverse order.
You can also redirect both a command’s input and output:
$ tac < list_az.txt > list_za.txt
The above does the same thing as the previous command, but in this case the results aren’t displayed on your screen. Because the output is redirected, the results are written to a file called
list_za.txt which then contains the same lines as
list_az.txt but in reverse order.
< Piping >
So far, we’ve examined redirecting the input and output of programs. But things are getting even better: you can actually take the output of one program and send it to another as the input. This is called piping. With pipes, you can “glue” multiple commands together in a powerful way. The following is maybe one of the most common ways of using pipes:
$ ls | less
In the example above, the standard output of
ls is sent to
less. This is especially useful if a directory has so much contents that they all don’t fit on your screen when you do
ls. When you send the results of the
less, you can scroll the directory listing. With this handy “
| less” thing you can scroll the output of any command.
You can use pipes with many commands, but one of the most common and useful ones is
grep is a program that examines every line of the standard input it gets and searches for a specified pattern of characters. Then it sends to standard output every line that contains those characters.
For example, suppose we have a text file called
applist.txt and we want to find out what lines of it contain the word “desktop”. It’s easy with pipes. We list the contents of the file
applist.txt and send the results to
grep, which then filters all lines containing the desired word “desktop”, and displays those lines on your screen:
$ cat applist.txt | grep desktop
grep is, like many Linux commands, case sensitive. This means that the above matches only “desktop”, not “Desktop” or “DESKTOP”. With the
-i option the search is case insensitive:
$ cat applist.txt | grep -i desktop
What if you’d like to scroll the output of
grep? Well, because
grep sends its results to standard output, you can just pipe them to
$ cat applist.txt | grep -i desktop | less
Of course you can redirect the output of
grep to a file, if you want:
$ cat applist.txt | grep -i desktop > desktop.txt
Input/output redirection is a very useful feature, and when you get more familiar with the CLI and learn more commands, you’ll start to appreciate this powerful feature more and more.