Pipes and subshells – your shell's salt and pepper

In this section, we will be looking at ways to improve your productivity using your shell. The Linux command line is great because it has a variety of tools we can use. What makes it even greater is the fact that we can chain these tools together to form greater, more powerful tools that will make us even more productive. We will not go into basic shell commands; instead we will be looking at some cool pipe and subshell combinations that can make our lives easier.

Let's start with a basic pipe; in this example, we are counting the length of the current path using the following command:

pwd | wc -c
Pipes and subshells – your shell's salt and pepper

pwd, as you probably know, stands for print working directory. The | is the pipe symbol, and what it does is send the output of the command on the left to the command on the right. In our case, pwd is sending its output to wc -c, which counts the number of characters. The coolest thing about pipes is that you can create a chain of any number of pipes.

Let's see another example where we will see how to find used space on the drive:

df -h | grep /home | tr -s " " | cut -f 2 -d " "
Pipes and subshells – your shell's salt and pepper

As you can see, the command printed out 173G, the size of the /home partition. This is a common use case when chaining multiple commands, each command reducing the output until we get the desired information and nothing else. In our case, this is the used disk space.

To count all the directories in a folder, use the following command:

ls -p | grep / | wc -l
Pipes and subshells – your shell's salt and pepper

The basic idea is to count all the lines that end with /. Here we can see we have only one directory.

Pipes are a great option to find and kill processes. Say we want to find the process ID of nautilus, and kill all running instances. For this we use:

ps aux | grep nautilus | grep -v grep | awk '{print $2}' | xargs kill
Pipes and subshells – your shell's salt and pepper

Now we've killed nautilus. This was purely a demonstrative example. There are other ways of doing this.

Let's open nautilus again and send it to the background by hitting Ctrl + Z followed by the bg command.

Now let's run the following command:

pgrep nautilus

To see all the pids of nautilus and to send the kill signal to all those processes, use the following command line:

pkill nautilus

Now it's time for some networking! You probably know the ifconfig command, which is used to print information about the network interfaces. To get the IP address of a specific interface (in our case the wireless interface wlp3s0), run this:

ifconfig wlp3s0 | grep "inet addr:" | awk '{print $2}' | cut -f 2 -d ":"
Pipes and subshells – your shell's salt and pepper

And now, we see your private ip address on the screen.

A common use case that might also arise is counting the word frequency in a file.

Here we have a standard lorem ipsum text contained in lorem.txt. In order to get the word frequency, use this:

cat lorem.txt | tr " " "\n" | grep -v "^\s*$" | sed "s/[,.]//g" | sort | uniq -c | sort -n
Pipes and subshells – your shell's salt and pepper

Append grep -w id to find the frequency of the word ID, or grep -w 4 to see all words that appear four times.

Now let's move on to our first subshell example. Subshells can be written by either enclosing them in $(), or using backticks (`). Backticks are usually found under the Esc key on your keyboard. In all our examples, we will be using the first form because it's easier to read.

Our first example is to list all the folders in our current folder:

ls $(ls)

The ls subshell returns the files and folders in the current directory and the ls from outside the subshell will list those individually, showing additional details:

Here, the subshell will return the number of entries (five, in this case). The number we are looking for is the number of entries minus the special folders ("." and ".."). In order to do arithmetic operations, we use the expr command, as in our example.

Notice that the subshell contains a pipe. The good thing is that we can combine pipes and subshells in any way in order to obtain the desired result.

Imagine pipes and subshells as Lego pieces for your shell. They expand way beyond its capabilities and give you access to new possibilities with infinite combinations. In the end, it all depends on your imagination and how well you learn to use them.