On some previous posts, I talked about the terminal. We’ve already discussed how to use it to launch programs, and some tricks to improve our usage of it. Now, I’ll show you a new level of things that you can achieve with a terminal window, more specifically, how you can run multiple programs together, and use the output of one program as an input to another one, or even read and write from files!

As always, I’m writing this with the bash terminal as a reference, since its the default on most linux distros. However, it should apply to other related terminals as well.

First of all, we need to understand the concept of redirection. Redirection is, as its name may suggest, the action of taking something, either from a program output or from a file, and moving it somewhere else, either to a file or to a program.

To redirect something, we use redirection operators or pipes, depending on what we’re redirecting from and to.

Redirection with files: >, < and >>

When a file is either the origin or the destination of the redirection, we use these operators and their. When using these, the “pointy” side of the operator points (rather intuitively) towards the destination, either program or file.

It is worth noting that in such case, the program name ALWAYS comes first, either if it is sending or receiving information. Using the filename first will show an error, specifying that no such program exists. Therefore, we have 4 possible combinations:

  • PROGRAM_NAME > FILE_NAME. Executes the program and redirects the output to a file named FILE_NAME. It will either create said file if it doesn’t exist, or rewrite its contents if it does.
  • PROGRAM_NAME >> FILE_NAME. Executes the program and redirects the output to a file named FILE_NAME. It will either create said file if it doesn’t exist, or add the program output to its current contents if it does.
  • PROGRAM_NAME < FILE_NAME. Executes the program, using the contents of FILE_NAME as an input. The contents of the file will be interpreted exactly as if they were typed on the terminal.
  • PROGRAM_NAME << END_TEXT. This is an special case, rather different from the rest. We’ll discuss it later on this post.

Here is a simple example:

Note the two programs executed here:

uname is a program with shows kernel info. Used with the -r option it shows the kernel release used by the system.

cat is a program which prints the specified file to the screen. In this case, it reads whatever is in the file “myfile” and prints it on the screen

On the second terminal line, the “>” operator takes the output of the uname -r call and redirects to the file we specified, in this case “myfile”. If there is an existing file with that name, > will erase its contents and write the program output. If there isn’t, it will create a file with such name. If we used >> and the file existed, its original content wouldn’t have been erased, but rather it would get the new contents appended (i.e. added at the end).

“Live” specifying input to a program: the << operator

In the previous section, I mentioned that the form PROGRAM_NAME << END_TEXT is an special case. That’s because it lets us specify the input for a program, with no files required. This is useful if we want to specify all the inputs for a program that asks them one by one, on a “single hit”.

After we type it, we can enter all the text we want (including multiple lines) until the END_TEXT (whatever it is) is typed on an empty line. For example:

After we type lolcat << done, we can enter all the text we want, until “done” is specified. Once we enter “done”, all what we’ve typed (except for the “done” itself) will be fed into the program as an input.

In the example, I use lolcat, a program that reads whatever its input is and prints it on a nice rainbow gradient.

Pipes (|)

Similarly to the redirection operators, we use pipes to redirect the output of one program to another, with no files involved. Pipes always work left-to-right, waiting for the program on the left to complete before using its output as input for the program on the right.

On the second terminal entry, we use the pipe operator to deliver the output of uname –help (as seen on the first entry) to the grep program, which has “version” as its argument.

The grep program searches for a word or phrase (or even a regular expression) in the text used as input, and shows the lines that have matches in them. In the previous example, it searches for the word “version” in the output of uname --help, highlights the matches and shows them, alongside their corresponding lines.

Featured image by Edge2Edge Media on Unsplash