Get into DevOps is a blog about methodologies, practices and tools to improve software delivery.

Starting in the shell: The Unix Pipe

Starting in the shell: The Unix Pipe

Let’s take a look at some of the command line tools that are commonly shipped with Unix-based computers. If you are using a Mac, you can try all of these out by launching Terminal.

Originating from the 70s, the design philosophy behind most of the Unix command line tools is that one tool should do just one thing, do it really well, and work with as many other tools as possible. You may notice some commonalities here with modern microservice paradigms.

In Unix-like systems, processes can be chained together with a pipe (the character | ). This will direct the standard output of a process to the standard input of the next process.

Let’s take an example; I want to see how many Javascript files related to testing are there in a code repository. Navigate to the code repository on your computer, for example /Users/mjuuso/git/my-app:

$ cd ~/git/my-app

(Tip: The $ character marks the shell prompt in these examples, i.e. the line where you write the commands. The character ~ translates to your home directory in all commands.)

Let’s use the find program to list all javascript files under this directory, and all subdirectories:

$ find . -iname "*.js"
./src/myclass.js
./src/myotherclass.js
./src/index.js
./src/server.js
./src/myclass.test.js
./src/myotherclass.test.js
./node_modules/lib/index.js
./node_modules/lib/class.test.js

You should get a potentially long list of files. How long, exactly? Let's pipe the output to a tiny program called wc, which is short for Word Count. Despite its name, it can also count lines with the -l argument:

$ find . -iname "*.js" | wc -l
    8

(Tip: Press the Up Arrow key on your keyboard to recall the last command you ran - this way you can do changes and additions easily.)

Okay, eight is a reasonable number of files. We can see in the output however that some of them are under node_modules, and we don't care about those. Let's filter them out with the grep command, argument -v to return lines that don't match the given pattern. And count the number of lines again:

$ find . -iname "*.js" | grep -v node_modules | wc -l
     6

Better. Now, which filenames include "test" in them? Let's use grep again, this time without the -v argument, to match only lines with the given pattern:

$ find . -iname "*.js" | grep -v node_modules | grep test
./src/myclass.test.js
./src/myotherclass.test.js

And get the number of lines, which is equal to the number of files:

$ find . -iname "*.js" | grep -v node_modules | grep test | wc -l
      2

You can see that there are 2 Javascript files outside of the node_modules directory that have the word "test" in their path. While not the most beautiful, the above command demonstrates piping well.

Simple chained commands are a very powerful tool, allowing you to extract and process information in versatile ways.

What is DevOps?

What is DevOps?