8  Customizing the command line

When you want to do something on your personal computer or phone, you just tap or click to make it happen. But servers generally have no graphical user interface (GUI) to be tapped or clicked. On a server, interaction is via the command line – an all-text interface where you type to indicate what you want to do.

Even if you’re not administering a server, it’s worth learning your way around the command line as a number of tasks are quicker and easier from the command line. Most people who learn the command line end up using it a lot on their personal computers.

Note

Server admin tasks are done via a graphical tool in some organizations, but this is a red flag.

It means that the organization is either trying to find relatively low-skill (cheap) admins who haven’t bothered to learn to use the command line or are using an intermediary tool to limit what IT/Admins can do. Either way, it’s going to be harder to get things done.

In this chapter, you’re going to learn to set up and customize the command line on your machine and to access a server via secure socket shell (SSH) – the administrative side door on a server.

8.1 Getting the command line you want

As you get started on the command line, you’ll soon realize that some customization is in order. Maybe the colors aren’t quite right, or you want shortcuts for commands you type a lot, or you want more information in the default display.

Some people might argue that customizing your command line isn’t the best use of your time and energy. Those people are no fun. Having a command line that behaves exactly as you like will speed up your work and make you feel like a hacker.

But as you get started, you’ll soon find yourself neck deep in Stack Overflow posts on how to customize your .bashrc. Or wait, is it the .zshrc? Or…

The reason customizing your command line is somewhat confusing is that the command line you interact with is actually two or three programs that sit on top of each other. You can mix-and-match options for each of them and configure them in a variety of ways.

Notes on operating systems

I’ve been using the command line in MacOS for many years, so I have strong opinions to share in this chapter.

I haven’t used a Windows machine in many years. I’ve collected some recommendations, but I can’t personally vouch for them the same way.

I don’t include Linux recommendations because people who use Linux on their desktop have already gone deep down the customization rabbit hole and don’t need my help wasting their time.

8.2 The terminal

The terminal is the GUI where you’ll type in commands. The terminal program you use will dictate the colors and themes available for the window, how tabs and panes work, and the keyboard shortcuts you’ll use to manage them.

Some programs you might use, like RStudio or VSCode have terminals built into them. If you do basically all your terminal work from one of these environments, you may not need another. But it can be nice to have a standalone terminal program you like.

I’d recommend against using the built-in terminal app (called Terminal). It’s fine, but there are better options.

My personal favorite is the free iTerm2, which adds a bunch of niceties like better theming and multiple tabs.

The built-in terminal is the favorite of many users. There are a variety of alternatives you can try, but feel free to stick with the default.

8.3 The shell

The shell is the program that takes the commands you’re typing and runs them. It’s what matches the words you type to actual commands or programs on your system. Depending on which shell you choose, you’ll get different options for plugins and themes.

The shell runs anywhere you’ve got a running operating system. So your computer has one shell and your server would have a different one. Even a Docker Container has a shell available. That means that if you do a lot of work on a server, you may need to configure your shell twice – once locally and once on the server.

The default shell for MacOS (and Linux) is called bash. I’d advise you to switch it out for zsh, which is the most popular bash alternative.1 Bash alternatives are programs that extend bash with various bells and whistles.

Relative to bash, zsh has a few advantages out of the box, like better auto-completion. It also has a huge ecosystem of themes to enhance visual appeal and functionality, and plugins that let your command line do everything from displaying your git status to controlling your Spotify playlist.

I’d recommend looking up instructions for how to install zsh using Homebrew.

Windows comes with two shells built in, the Command Shell (cmd) and the PowerShell.

The Command Shell is older and has been superseded by PowerShell. If you’re just getting started, you should just work with PowerShell. If you’ve been using Command Shell on a Windows machine for a long time, most Command Shell commands work in PowerShell, so it may be worth switching over.

8.4 Configuration management

Now that you’ve got your shell and terminal installed, you’ll want to customize. It is possible to directly customize both zsh and PowerShell. But the best way to configure them is to use a configuration manager for your themes and plugins.

Prezto is my favorite configuration and plugin manager for zsh. OhMyZsh is also popular and very good. Feel free to choose either, but you can only use one.

Once you’ve installed Prezto, you’ve got (at least) three different places you could configure your command line – the iTerm2 preferences, .zshrc, and .zpreztorc. I’d recommend leaving .zshrc alone, customizing the look of the window and the tab behavior in the iTerm2 preferences, and customizing the text theme and plugins via Prezto in the .zpreztorc file.

I tend to be a pretty light on customization, but I’d recommend looking into git plugins and some of the advanced auto-completion and command history search functionality.

Many people like customizing PowerShell with Oh My Posh.

8.5 Text Editors

If you’re working on your command line a lot, you’ll probably be working inside text editors a fair bit. There are many, many options for text editors and people have strong preferences.

Mac OS’s default text editor is called TextEdit and it’s bad. Don’t use it. Windows users get Notepad, which is somewhat better than TextEdit, but still not the best option out there.

If you like, you can just edit text files inside your IDE of choice like VS Code or RStudio. Others may prefer a standalone text editor. The most popular these days are probably Sublime or Notepad++ (Windows Only).

Unlike with the terminal, there’s no deep configuration here. Install one from the web, configure it as you like, and make sure it’s the default for opening .txt and other files you might want to edit in your system preferences.

8.6 Secure server connections with SSH

One common IT/Admin task is remotely accessing a server from the command line on your machine. SSH – short for Secure (Socket) Shell – is a tool for making a secure connection to another computer over an unsecured network. It’s most often used to interact with a server’s command line from the command line of your computer.

Using SSH requires invoking the ssh command line interface from your computer (local host) with a username and the address of the remote host (server). For example, connecting to the server at server.example.com as the user alex

Terminal
> ssh alex@server.example.com

Once you run this command, your terminal will open a session to the terminal of the server.

8.6.1 Understanding SSH keys

Before any of this can work, you’ll have to configure your SSH keys, which come in a set called keypair. Each keypair consists of a public key and a private key. You’ll register your public key anywhere you’re trying to SSH to, like a server or git host, but your private key must be treated as a precious secret.

When you use the ssh command, your local machine sends a request to open an SSH session to the remote and includes the private key with the request. The remote host verifies the private key with the public key and opens an encrypted connection.

A diagram of SSH initialization. The local host sends the private key, the remote checks against the public key, and then opens the session.

This seems weird – how can you verify your secret identity with something that you can just spread around publicly? The answer is public key cryptography, which makes it easy to check whether a proffered private key is valid, but nearly impossible to fabricate a private key from a public key.

Note

I wish public and private keys were named differently. Calling the private key the key and the public key the lock makes the intent much clearer. But no one asked me.

The key to public key cryptography is mathematical operations that are easy in one direction but really hard to reverse. As a simple example, think of the number \(91\) and its prime factors. Do you know what the prime factors of \(91\) are offhand? I do not.

It’ll probably take you a few minutes to try a bunch, even if you use a calculator. But if I give you the numbers \(7\) and \(13\), it’s easy to verify that \(7 * 13 = 91\).

In this example, the number \(91\) would be the public key and the prime numbers \(7\) and \(13\) together would be the private key. This wouldn’t actually make for very good public key cryptography because it doesn’t take more than a few moments to figure out that \(7\) and \(13\) are prime factors of \(91\).

In real public key cryptography, the idea is similar, but the mathematical operations are more complex and the numbers much, much bigger. So much so that it’s basically impossible to break public SSH keys through guessing.

But that doesn’t make SSH foolproof. While it’s basically impossible to fabricate a private key, it’s totally possible to steal one. Your private key must be kept secret. The best practice is to never move it from the computer where it was created and to never share them.

In summary, do what you want with your public keys, but don’t share your private keys. Don’t share your private keys. Seriously, do not share your private keys.

8.7 Practical SSH usage

Now that you’ve got an understanding of how SSH works, the steps should be easy to remember.

  1. Create an SSH keypair on any machine you’ll be SSH-ing from (local host).
  2. Put the public key anywhere you’ll be SSH-ing to (remote host).
  3. Use the ssh command to connect.

If you’re working on a server, you’ll probably create at least two keypairs. One on your personal computer to SSH to the server, and one on the server to access outside services that use SSH, like GitHub.

8.7.1 Step 1: Create Keypair

You’ll create a keypair on any server you’re SSH-ing from.

To create an SSH keypair, you should just follow a tutorial online. The keypair will have two parts. The one that ends in .pub is – you guessed it – the public key.

In most cases, you’ll only create one private key on each machine. If you follow standard instructions for creating a key, it will use the default name, probably id_ed25519.2 Sticking with the default name is great because the ssh command will automatically use them. If you don’t use the default name, you’ll have to specify.

Note

Remember, you should never move your private key. If you think the answer to a problem you’re having is to move your private key, think again.

Instead of moving your private key, create a new private key on the machine where you need to use SSH and register a second public key on the remote.

Some organizations require that you have a unique key for each service you’re using to make it easier to swap keys in the event of a breach. If so, you won’t be able to use the default key names.

8.7.2 Step 2: Register the public keys

To register a public key to SSH into a server, you’ll add the public key to the end of the user’s .ssh/authorized_keys file in their home directory. You’ll have to make sure the permissions on the authorized_keys file are correct. More on that in Chapter 9.

If you’re registering with a service, like GitHub.com, there’s probably a text box in the GUI to add an SSH key. Google for instructions on how to do it.

8.7.3 Step 3: Use SSH

To use SSH, you type ssh <user>@<host>. There are also other commands that can use SSH under the hood, like git or scp.

For Windows users

For a long time, Windows didn’t support SSH out of the box, so SSH-ing from Windows required a separate utility called PuTTY. More recent versions of Windows support using SSH directly in PowerShell or in Windows Subsystem for Linux (WSL). If SSH isn’t enabled on your machine, Google for instructions.

If you have multiple SSH keys or didn’t use the default flag, you can specify a particular key with the -i flag.

If you’re using SSH a lot, I’d recommend setting up an SSH config file. An SSH config file allows you to create aliases that are shortcuts to SSH commands including users, hosts, and other details. So if you had a long SSH command like ssh -i my-ssh-key alex@server.example.com, you could shorten it to ssh alex-server or whatever you want.

One annoyance about SSH is that they block the terminal they’re using and will break when your computer goes to sleep. Many people also like using the tmux command line utility with SSH to help solve these issues.

tmux is a terminal multiplexer, which allows you to manipulate terminal sessions from the command line, including putting sessions into the background and making sessions durable through sleeps and other operations. To be honest, I’m mentioning tmux because lots of people love it, but I’ve found the learning curve too steep for it to come into regular usage for me. Your mileage may vary.

If you ever run into trouble using SSH, it has one of my favorite debugging modes. Just add a -v to your command for verbose mode. If that’s not enough information, add another v for more verbosity, and if that’s not enough, just add another v for super verbose mode.

8.8 Comprehension Questions

  1. Draw a mental map that includes the following: terminal, shell, theme manager, operating system, my laptop
  2. Under what circumstances should you move or share your SSH private key?
  3. What is it about SSH public keys that makes them safe to share?

8.9 Lab: Login to the server

In the last chapter we got your server up and running. In this lab, we’ll use the provided .pem key to log in for the first time.

8.9.1 Step 1: Grab the server address

From the EC2 page, you can click on the instance ID in blue to see all the details of about your server.

Copy the Public IPv4 DNS address, which starts with \(\text{ec2-}\) and ends with \(\text{amazonaws.com}\). That little icon on the left of the address copies it. You’ll need it throughout the labs. If you lose it, come back here to get it.

Set a Server Address Variable

In the rest of the labs in this book, I’m going to write the commands using the bash variable SERVER_ADDRESS. That means that if you create that variable, you’ll be able to just copy the commands out of the book.

For example, as I write this, my server has the address \(\text{ec2-54-159-134-39.compute-1.amazonaws.com}\). So would set my server address variable on my command line with SERVER_ADDRESS=ec2-54-159-134-39.compute-1.amazonaws.com.

If you’re used to R or Python, where it’s best practice to put spaces around =, notice that assigning variables in bash requires no spaces around =.

8.9.2 Step 2: Log on with the .pem key

The .pem key you downloaded when you set up the server is the private key for a pre-registered keypair that will let you SSH into your server as the admin user (named ubuntu on a Ubuntu system).

The .pem key is just an SSH key, so you can SSH to your server with

Terminal
ssh -i do4ds-lab-key.pem \
  ubuntu@SERVER_ADDRESS

When you first try this, you’re probably going to get an alert that looks something like this:


\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@

\@ WARNING: UNPROTECTED PRIVATE KEY FILE! \@

\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@

Permissions 0644 for 'do4ds-lab-key.pem' are too open.

It is required that your private key files are NOT accessible by others.

This private key will be ignored.

Load key "do4ds-lab-key.pem": bad permissions

ubuntu@ec2-54-159-134-39.compute-1.amazonaws.com: Permission denied (publickey).

Because the keypair is so powerful, AWS requires that you restrict the access pretty severely. Before you can use it to open the server, you’ll need to change the permissions. We’ll get into permissions in Chapter 9. Until then, you can just change the permissions by navigating to the right directory with the cd command and running chmod 600 do4ds-lab-key.pem.

Once you’ve done that, you should be able to login to your machine as the root user. When you want to exit an SSH session and get back to your machine, you can just type exit.

8.9.3 Step 3: Create your own SSH key

You really shouldn’t use the AWS-provided .pem key to login to your server after the first time. It’s too powerful. Create a normal SSH key using the instructions earlier in this chapter. In the next lab, we’ll get that SSH key configured for your user on the server.


  1. zsh is pronounced by just speaking the letters aloud, zee-ess-aitch. Some people might disagree and say it’s zeesh, but they’re not writing this book, are they?↩︎

  2. The pattern is id_<encryption type>. ed25519 is the standard SSH key encryption type as of this writing.↩︎