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.
Author: Nana Långstedt < nana.langstedt at gmail.com >
tuXfile created: 20 December 2001
Last modified: 22 September 2005
- 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 ls and cat commands. 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 File2:
$ 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 sound.wav!
- 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 tac to 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?
me@puter: ~$ tac
stupid useless random
stupid useless random
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.
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 ls command to 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. 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
Note that 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 less:
$ 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.