Barnicoz Tech Barnicoz Tech Author
Title: How to Use Pipes on Linux
Author: Barnicoz Tech
Rating 5 of 5 Des:
Use Linux pipes to choreograph how command-line utilities collaborate. Simplify complex processes and boost your productivity by...

Linux terminal on a laptop
Use Linux pipes to choreograph how command-line utilities collaborate. Simplify complex processes and boost your productivity by harnessing a collection of standalone commands and turning them into a single-minded team. We show you how.

Pipes Are Everywhere

Pipes are one of the most useful command-line features that Linux and Unix-like operating systems have. Pipes are used in countless ways. Look at any Linux command line article—on any web site, not just ours—and you’ll see that pipes make an appearance more often than not. I reviewed some of How-To Geek’s Linux articles, and pipes are used in all of them, one way or another.
Linux pipes allow you to perform actions that are not supported out-of-the-box by the shell. But because the Linux design philosophy is to have many small utilities that perform their dedicated function very well, and without needless functionality—the “do one thing and do it well” mantra—you can plumb strings of commands together with pipes so that the output of one command becomes the input of another. Each command you pipe in brings its unique talent to the team, and soon you find you’ve assembled a winning squad.

A Simple Example

Suppose we have a directory full of many different types of file. We want to know how many files of a certain type are in that directory. There are other ways to do this, but the object of this exercise is to introduce pipes, so we’re going to do it with pipes.
We can get a listing of the files easily using ls:
ls
Collection if files in a directory, in a terminal window
To separate out the file type of interest, we’ll use grep. We want to find files that have the word “page” in their filename or file extension.
We will use the shell special character “|” to pipe the output from ls into grep.
ls | grep "page"
ls -l | grep "page" in a terminal window
grep prints lines that match its search pattern. So this gives us a listing containing only “.page” files.
listing of page files in a terminal window
Even this trivial example displays the functionality of pipes. The output from ls was not sent to the terminal window. It was sent to grep as data for the grep command to work with. The output we see comes from grep, which is the last command in this chain.

Extending Our Chain

Let’s start extending our chain of piped commands. We can count the “.page” files by adding the wc command. We will use the -l (line count) option with wc. Note we’ve also added the -l (long format) option to ls . We’ll be using this shortly.
ls - | grep "page" | wc -l
ls - | grep "page" | wc -l in a terminal window
grep is no longer the last command in the chain, so we don’t see its output. The output from grep is fed into the wc command. The output we see in the terminal window is from wc. wc reports that there are 69 “.page” files in the directory.
Let’s extend things again. We’ll take the wc command off the command line and replace it with awk. There are nine columns in the output from ls with the -l (long format) option. We’ll use awk to print columns five, three, and nine. These are the size, owner, and name of the file.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}'
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' in a terminal window
We get a listing of those columns, for each of the matching files.
Three column listing for each matching file in a terminal window
We’ll now pass that output through the sort command. We’ll use the -n (numeric) option to let sort know the first column should be treated as numbers.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n in a terminal window
The output is now sorted in file size order, with our customized selection of three columns.
Files sorted by size in a terminal window

Adding Another Command

We’ll finish off by adding in the tail command. We’ll tell it to list the last five lines of output only.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5 in a terminal window
This means our command translates to something like “show me the five largest “.page” files in this directory, ordered by size.” Of course, there is no command to accomplish that, but by using pipes, we’ve created our own. We could add this—or any other long command—as an alias or shell function to save all the typing.
Here is the output:
Five largest .page files listed by size order in a terminal window
We could reverse the size order by adding the -r (reverse) option to the sort command, and using head instead of tail  to pick the lines from the top of the output.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -rn | head -5 in a terminal window
This time the five largest “.page” files are listed from largest to smallest:
Five largest .page files listed in reverse size order in a terminal window

Some Recent Examples

Here are two interesting examples from recent How-To geek articles.
Some commands, such as the xargscommand, are designed to have input piped to them. Here’s a way we can have wc count the words, characters, and lines in multiple files, by piping ls into xargs which then feeds the list of filenames to wc as though they had been passed to wc as command line parameters.
ls *.page | xargs wc
ls *.page | xargs wc in a terminal window
The total numbers of words, characters, and lines are listed at the bottom of the terminal window.
Count of words, charcaters, and lines in a terminal window
Here’s a way to get a sorted list of the unique file extensions in the current directory, with a count of each type.
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c in a terminal window
There’s a lot going on here.
The output shows the list of file extensions, sorted alphabetically with a count of each unique type.
List of unique file extensions in a terminal window

Named Pipes

There’s another type of pipe available to us, called named pipes. The pipes in the previous examples are created on-the-fly by the shell when it processes the command line. The pipes are created, used, and then discarded. They are transient and leave no trace of themselves. They exist only for as long as the command using them is running.
Named pipes appear as persistent objects in the filesystem, so you can see them using ls. They’re persistent because they will survive a reboot of the computer—although any unread data in them at that time will be discarded.
Named pipes were used a lot at one time to allow different processes to send and receive data, but I haven’t seen them used that way for a long time. No doubt there are people out there still using them to great effect, but I’ve not encountered any recently. But for completeness’ sake, or just to satisfy your curiosity, here’s how you can use them.
Named pipes are created with the mkfifo command. This command will create a named pipe called “geek-pipe” in the current directory.
mkfifo geek-pipe
mkfifo geek-pipe in a terminal window
We can see the details of the named pipe if we use the ls command with the -l (long format) option:
ls -l geek-pipe
ls -l geek-pipe in a terminal window
The first character of the listing is a “p”, meaning it is a pipe. If it was a “d”, it would mean the file system object is a directory, and a dash “-” would mean it is a regular file.

Using the Named Pipe

Let’s use our pipe. The unnamed pipes we used in our previous examples passed the data immediately from the sending command to the receiving command. Data sent through a named pipe will stay in the pipe until it is read. The data is actually held in memory, so the size of the named pipe will not vary in ls listings whether there is data in it or not.
We’re going to use two terminal windows for this example. I’ll use the label:
# Terminal-1
in one terminal window and
# Terminal-2
in the other, so you can differentiate between them. The hash “#” tells the shell that what follows is a comment, and to ignore it.
Let’s take the entirety of our previous example and redirect that into the named pipe. So we’re using both unnamed and named pipes in one command:
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipe
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipe in a terminal window
Nothing much will appear to happen. You may notice that you don’t get returned to the command prompt though, so something is going on.
In the other terminal window, issue this command:
cat < geek-pipe
cat < geek-pipe in a terminal window
We’re redirecting the contents of the named pipe into cat, so that cat will display that content in the second terminal window. Here’s the output:
The contents of the named piped shown in a terminal window
And you’ll see that you have been returned to the command prompt in the first terminal window.
Completed task and the command prompt in in a terminal window
So, what just happened.
  • We redirected some output into the named pipe.
  • The first terminal window did not return to the command prompt.
  • The data remained in the pipe until it was read from the pipe in the second terminal.
  • We were returned to the command prompt in the first terminal window.
You may be thinking that you could run the command in the first terminal window as a background task by adding an & to the end of the command. And you’d be right. In that case, we would have been returned to the command prompt immediately.
The point of not using background processing was to highlight that a named pipe is a blocking process. Putting something into a named pipe only opens one end of the pipe. The other end isn’t opened until the reading program extracts the data. The kernel suspends the process in the first terminal window until the data is read from the other end of the pipe.

The Power of Pipes

Nowadays, named pipes are something of a novelty act.
Plain old Linux pipes, on the other hand, are one of the most useful tools you can have in your terminal window toolkit. The Linux command line starts to come alive for you, and you get a whole new power-up when you can orchestrate a collection of commands to produce one cohesive performance.
Parting hint: It is best to write your piped commands by adding one command at a time and getting that portion to work, then piping in the next command.

About Author

Advertisement

Post a Comment

  1. A common mistake almost everyone makes is to start the search when half the month has passed. You shouldn’t do that. Better apartments often get picked up by other people at the first third of the month. If you search for Furnished Apartment for rent in Dhaka at different stages of a month, you will get completely different results. So, If you are determined to get an apartment you would love to have, you should start searching at the first stage of the month too. I would recommend starting the search 2 months earlier. The broader range of time you get the possibility of finding the right apartment increases.

    ReplyDelete

 
Top