Mastering the Terminal to Improve Development Speed

Git, grep, tmux, and other useful commands to help you code faster & smarter!

Keith Galli
Posh Engineering
11 min readDec 7, 2020

--

Introduction

When I was new to programming, there was nothing more impressive than watching an expert navigate around a terminal. They could be doing something as simple as editing a text file, but from the outside perspective, it was awe-inspiring. A wizard at the keys, churning out lines of codes without the need to even glance at their mouse. Fast forward several years, and I have slowly acquired the art of the terminal. In this post, I will share several techniques that can be used to speed up development processes. We will specifically cover topics such as grep, tmux, aliasing, and several others. Let’s get started!

Setup

The first step to speeding up your workflow with the command line is making sure that you have a terminal that will work for your needs.

If you are using macOS or Linux, you will be all set with your default terminal.

If you are using Windows, I recommend downloading Windows Subsystem for Linux (WSL) for a bash terminal. This will provide much more functionality than is built into your default Command Prompt. Traversy Media has a good video walking through this process. My current preference is to also download Windows Terminal and configure it to open WSL by default for a more visually appealing terminal experience. Once done, you’ll have the full powers of Linux at your fingertips!

What can you do in the terminal?

The terminal is a one stop shop for all items related to your machine. You can use the terminal to understand system performance, edit code & text files, kill processes, and much much more. A better question than “What can you do in the terminal?” would be “What can’t you do in the terminal?”.

As a brief sampling of the space, here is a list of a few commands and what they do:

curl - transfer data to/from a URL (make get/post requests)
df - see disk space usage
diff - difference between files or directories
killall - terminate processes by name
locate - find the path to a file by name
ls - list all files in a directory
man - learn more about a command
ping - check connectivity status to a server.
ssh - connect to a different machine (remote in)
top - list all processes/threads of the Linux/macOS kernel
zip - compress files into a zip archive

You can also use bash scripts to link multiple commands together.

If you have never used a terminal before, learning the basics will probably be beneficial before reading the rest of this article. That will allow you to quickly jump around to different files and locations which will help you more effectively leverage the rest of the commands we highlight. Joe Collins has produced an excellent video to help you get started.

Topics to Master

You can do tons in the terminal. The following are a few examples of tools/commands that I use on a daily basis and that I think are especially useful to know well.

Vim — edit text/code files

One of the most frequent tasks you will likely find yourself doing in the command line is editing the contents of files. There are many terminal-based text editors (nano, emacs, vi, etc.), but my personal favorite is vim. There is a learning curve to editing files with this program like this, but as you get good you will likely find that a lot of changes can be made quicker than in modern text editors like Sublime Text or VS Code. To start learning more about vim, I recommend this tutorial by Ben Awad.

Git — version control

If you are working on a software project as part of a team, you are most likely using version control. Version control allows teams and individuals to more easily track and manage changes to software projects over time. Git is the most popular version control system. To most effectively leverage the powers of git, you will want to use its command line interface. Corey Schafer has produced a good series of videos to overview a lot of the important concepts here.

In my personal experience, Git has been an integral skill for any software team that I have been part of. It is a skill that takes time to curate and even after years of experience you will find yourself learning new tips & tricks. Developing expertise here will help make you a leader of any engineering team.

Grep — search for a word, phrase, or pattern

Probably my favorite command is Grep. When I’m working on a large software project, I often want to track down the locations of specific functions or classes and their usage, but I might not remember exactly what they are called or their relative locations. Instead of slowly working my way through each file and looking, I like to run a recursive grep command to do the search:

$ grep -r “text to look for”

This command traverses recursively through each folder in my current working directory and prints out each file and line number where a match is found. This allows me to know where I need to make my edits if I am trying to extend functionality or make some other type of edits. This is just one example of Grep, but there are many other areas that are useful. I also find leveraging grep’s ability to search for text using regex patterns particularly useful. In addition, piping other commands into grep can be very powerful (I’ll show an example of this later on).

Sed — transform text in a file or directory

Let’s say we just finished writing a Python script when we realize that a variable that we used consistently throughout didn’t adhere to the PEP 8 naming conventions. From our command line, we can easily make quick text transformations using the sed command. The following command:

$ sed -i 's/myVariable/my_variable/g' my_file.py

will replace all occurrences of our camelCase variable name with its equivalent in lowercase_with_underscores format. This becomes increasingly useful when you apply the functionality to many files at once. If in the above example we needed to make the replacement for an entire repository of code, we can link the find & sed commands together:

$ find . -type f -exec sed -i 's/myVariable/my_variable/g' {} +

This will replace every occurrence of the name in all files in our current working directory (including files nested further down within folders).

Scripting — run your code from the terminal

Before we move on to the next section, it is worth mentioning that any code that you write should be executable from the terminal. The specific command to do this depends on the language that you are working with. Most of my development efforts are in Python. Running Python scripts from the terminal can be done with the following:

$ python my_file.py

For other languages, a simple google search like “How to run <insert-language> code from the terminal” should help you find what you are looking for.

Running Previous Commands

Once you’ve started finding a set of terminal commands that you find useful, the next step is making sure that you can remember them. No matter how frequently you use the terminal, commands are going to escape your mind from time to time. This is especially true when the commands will often include several flags and file paths. Luckily our terminals offer tools that make it very easy to find and run previous commands without too much effort.

To get started, repeatedly pressing the up arrow on your keyboard will cycle you through your previous commands. This is very helpful if you switch back and forth between a few commands in a short period of time.

If the command you want to run was less recently used, you’ll probably want to use the history command instead. The result of this will be a list of your previous commands up to some set limit (1000 on my machine)

I’m able to easily run commands in this list in a few different ways. First I can type in !<Command Number> to run a specific line. In the above image, I could type !1989 to run the command cmatrix (ps I recommend running this command, it’s pretty fun xD).

You can also type an exclamation and then the start of the command you want to run and you will execute the first line that starts with that string. As an example, If I typed in !ma that would match and execute the command
man grep. That was the last command that started with the string “ma”.

Additionally, you can use the special syntax !! to run your previous command. One use case of this is if you forgot to run your previous command with admin privileges, you can simply run sudo !!

Building upon these concepts, you can link history with the grep command as a powerful duo. Typing in history | grep “docker” would search your history for all commands that include the word “docker”.

If you want a more interactive way to do this search, I recommend pressing Ctrl+r and then start typing the command you want to execute. This will do a search through your command history and grab the first one that includes the string you type in. You can continue pressing Ctrl+r to cycle through the commands that include the string you have typed in.

If you want a more permanent solution to easily be able to access commands you use frequently, I recommend aliasing. Aliasing allows you to define a new command as a shortcut to a longer command. An example where I use this is with visualizing my git tree. I frequently like to run the command:

$ git log --oneline --graph --color --decorate --all

To make it easier to run this command, I created an alias called gitlog that equals this longer command. To define an alias you can edit your .bashrc file ($ vim ~/.bashrc) and add a line as follows. It doesn’t matter where you add this line.

Now when you are trying to use the same command, it is as simple as typing

$ gitlog

(Note that you have to open up a new terminal or run source ~/.bashrc for the alias to first take effect)

Aliasing works great for any command that is hard to remember and that you run frequently. I personally use aliases in a variety of ways. From leveraging them to more easily navigate to complex folder locations to using them to simplify docker commands with lots of feature flags.

Terminal Multiplexer

Now that you have built up an arsenal of commands and you know how to always find them, you’ll need plenty of screen space to run them all. Terminal Multiplexer, or tmux for short, is a great option to help you do this. Tmux can allow you to split a single terminal window into many. It can also allow you to “detach” a terminal window. This is particularly useful if you want to run a continuous process in the background.

To get started with tmux, you will have to install it.

On Ubuntu this can be done with (Windows Subsystem for Linux):
$ sudo apt install tmux

On macOS this can be done with:
$ brew install tmux

Once installed, we can start a new tmux session by typing in tmux in our terminal. This will enter us into a blank terminal in a new window. In the next few sections we will highlight some of the basics of using tmux. For a comprehensive list of functionality, check out this cheat sheet.

Managing a single session

We can split our screen vertically with Ctrl+b, %
We can split our screen horizontally with Ctrl+b,

You can repeat these two commands to do more and more splits.

If you want to make windows an equal size vertically, use Ctrl+b, Alt+1
If you want to make windows an equal size horizontally, use Ctrl+b, Alt+2
If you want to make windows tiled, use Ctrl+b, Alt+5

To navigate between each window you can use Ctrl+b, o to cycle through each pane. You can also use Ctrl+b then an arrow key to specify which pane you want to navigate to. To close a pane you can type exit.

Having multiple sessions

Sometimes you might be working on several different tasks that you want to keep more logically separated than just splitting your screen. Tmux offers the ability to create multiple sessions which is very beneficial here. When we type in the command tmux we have created a session. We can run commands as we would like and then we can detach from the session by typing Ctrl+b, d. This gets us out of the session, but preserves its state. This can allow us to run commands in the background of our machine. If we want to reattach to the session we can run tmux a. If we do want to close it, we can type in exit from each pane the session.

We can also have multiple sessions running at the same time. To create our first session we can run tmux as well as optionally specifying a name

$ tmux new -s <name>

Next, let’s detach from this session (Ctrl+b, d) and create another new one

$ tmux new -s <another-name>

Again, let’s detach from this session (Ctrl+b, d).

If we type in tmux ls we will see all of the sessions we created. We can reattach to a specific one by doing

$ tmux a -t <name>

This type of workflow is very useful for launching long-running jobs, like training a deep neural network.

Conclusion

I hope that this article gave you some inspiration for some ways you can speed up your development efforts using the command line. Learning to effectively use the command line takes time. Try incorporating the terminal a bit more each day and before you know it you will be using it for almost everything. While there was a lot of useful information covered in this article, it is also important to remember to have fun with whatever you are doing. With that, I will leave you with one last command cowsay. A personal favorite of mine :).

If you’re interested in solving interesting problems with passionate engineers, apply to join our team and help us build the future of conversational AI!

--

--