Developer Tools: The Command Line
Tags: beginners, career, tools
Published: 2019-02-28 22:17:08

---
title: Developer Tools: The Command Line
published: true
description: Getting a great command prompt
cover_image: https://thepracticaldev.s3.amazonaws.com/i/u5akcyhn5v1cp0mbh3nv.png
series: Learning Developer Tools
tags: beginner, career, tools
---

Hello again!

Welcome to the next post in this series! Today we're gonna be going over some the command line and terminal emulators. Again, this is a topic that changes quite a lot between operating systems, so check out [the second post in the series](https://dev.to/wuz/developer-tools-the-operating-system-3n55) for some good options! Let's jump right in!

# Terminal Emulators

Let's take a trip down memory lane. Back in the early days of computing, not everyone had their own computer. Instead, an institution might have a computer that it allowed its staff to use. To access this computer, you might have had a basic monitor and a keyboard setup, like the [VT100](https://en.wikipedia.org/wiki/VT100). This setup was called a terminal and it allowed you to enter commands that were processed by the main computer. Jump forward to today and you might be using something like Terminal.app, iTerm, kitty, or Gnome Terminal. These are called terminal emulators - they are software designed to act like the old school terminals and allow you to input and output from a computer. The only difference is that the computer you are working with is right in front of you, not in a different building on campus. 

You might be wondering why we use something that imitates an old concept - don't we have GUI's and tools for this now? In some ways, you are right - many of the old tools have been replaced by more graphical alternatives. But as it turns out, text is still a great way to interact with a computer. Until we have great voice commands built into all software, text is the fastest way to do many things. 

# The shell

Now we know what kind of programs we can use to interact with the computer using text. The shell is the program that reads that text and decides what to do. It takes a string like `git commit -m 'Add the things!'` and decides that it should route to `git` and needs to pass the parameters `commit -m 'Add the things!'`. They take a program and wrap around the execution of it, like a shell. 😉 

There are lots of different shell programs, all with their own features. Many add widgets and simplifications to make you more productive, which often hides the actual functionality of a shell program. Some have fancy ways to interact with your previous commands and others integrate programming languages like Python directly into the shell. It's also worth noting that in addition to being programs that you can run, each of these shells is a programming language that allows you to write command line functions and programs.

## Bash

[Bash](https://www.gnu.org/software/bash/) (Bourne Again SHell) is the default shell on most Unix operating systems. It has a lot of great features, like Tab completion and aliases. This is the shell I use - I like it because there are lots of great resources out there and it doesn't do too much. It's kind of the baseline for the good shells and many others are based in part on the ideas set forward by Bash. Bash is also integrated on Windows now, which makes switch computers/OS's much easier.

## zsh

[zsh](http://zsh.sourceforge.net/) (z-shell) is basically a more interactive version of Bash. In addition to Tab completion, it features type ahead search and autocomplete. Most people who use zsh install [ohmyzsh](https://ohmyz.sh/), which gives you some really good defaults for your shell. This is often a good choice for newer devs as it has lots of user-friendly features and a good community around it. 

## fish

[fish](https://fishshell.com/) is pretty similar to zsh. It's got a lot of great user-friendly features. Fish has good syntax highlighting, which can be nice! Julia Evans has a great article on the benefits of [fish](https://jvns.ca/blog/2017/04/23/the-fish-shell-is-awesome/). I am thinking about switching to this in the future to play around with it.

Todd likes fish and shared in the comments:

{% devcomment 95k8 %}

## xonsh

[xonsh](https://xon.sh/index.html) is cross-platform and deeply integrations Python into the shell experience. If you like Python and don't like writing shell scripts, this might be a good option! 

## The others

There are a _lot_ of shell programs. People have lots of opinions on these things. Experiment a bit and see what programs you like the most. Searching for "alternatives to bash" is a good place to find some starting places.

# The Command Prompt

Now that we know what a terminal emulator is and how a shell works, let's talk about the command prompt. The command prompt is where you are going to type your commands - it's prompting you for input, which will be passed to the shell, which will decide how to respond. You'll most likely get some sort of output back, perhaps another string or a graphical program opening. Just like the shell, there are lots of possibilities when working with your command prompt. How they are displayed is usually handled by the shell, but the basic way to do it is to set an environment variable named PS1. Environment variables are global variables that tell your shell how to behave - they describe the environment that it is operating in.

---
 
If you are interested in reading a bit more about all this terminology, [this StackOverflow answer](https://stackoverflow.com/a/21016640/1466592) is really good.

# Some basic commands 

- `cd <directory>` - change to `<directory>` - Example: `cd ~/Projects`
- `ls <directory>` - list the files in `<directory>` - Example: `ls ~/Projects`
- `cp <file> <location>` - copy the `<file>` to `<location>` - Example: `cp ~/Projects/test.txt ~/textfile.txt`

If you want to learn more, I'd recommend checking [this tutorial](https://swcarpentry.github.io/shell-novice/) out.

# Giving your shell superpowers

Once you have a shell, you'll want to upgrade it to fit your workflow! 

## Looking good!

First, let start by making a good-looking prompt. In most shells, this is done by changing the PS1 enviroment variable. To start make a file in your home folder (you can get there by opening a terminal and typeing `cd ~`). Let's create a file called `.bash_prompt`. If you have VS Code installed, just run `code .bash_prompt`.

Once that file opens up, put this at the top:

```sh
#!/usr/bin/env bash

# Shell prompt
## Based on wuz/.files (github.com/wuz/.files)

bold="\[\e[1m\]"
reset="\[\e[0m\]"
black="\[\e[30m\]"
blue="\[\e[34m\]"
green="\[\e[32m\]"
cyan="\[\e[36m\]"
red="\[\e[31m\]"
yellow="\[\e[33m\]"
purple="\[\e[35m\]"
brown="\[\e[33m\]"
gray="\[\e[37m\]"
dark_gray="\[\e[90m\]"
light_blue="\[\e[94m\]"
light_green="\[\e[92m\]"
light_cyan="\[\e[96m\]"
light_red="\[\e[91m\]"
light_purple="\[\e[95m\]"
light_yellow="\[\e[93m\]"
white="\[\e[97m\]"

```

This gives us a bunch of colors to work with. Just for the record, those colors are described in [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code).

Now that we have some colors set up, let's make a new prompt. Add this directly below what you have set up there.

```sh

# ^ rest of file ^

dir_chomp() {
  if [ $PWD == $HOME ]; then
    echo "~";
  else
    local ns="${PWD//_/ }"
    local nh="${ns/#$HOME/\~}";
    local wd="${nh%/*}";
    local wdnhrd=`echo $wd | sed -e "s;\(/.\)[^/]*;\1;g"`
    echo "$wdnhrd/${ns##*/}";
  fi
}

# Set the terminal title and prompt.
PS1="${bold}${light_green}\$(dir_chomp)${white}";
PS1+="${blue}${bold}\n→ ${reset}"
export PS1;
```

Here we are creating a function called dir_chomp, which takes a directory like `~/Projects/Work/app` and converts it into `~/P/W/app`. If you don't like that, replace this line: `PS1="${bold}${light_green}$(dir_chomp)${white}";` with `PS1="${bold}${light_green}\w${white}";`. That will show the full directory path. We are also setting some colors, using the variables we defined above. With those variables, they will make all characters after them that color until they reach a `${reset}` or another color variable.

Now that we have that in there, you can type `source ~/.bash_prompt` and you should be able to see your new prompt! Try navigating around with `cd` and see the directory change above the `→` character. If you like it, run `code .bashrc` and add this to the end of the file:

```sh
# end of ~/.bashrc

source ~/.bash_prompt
```

Now it should stick to your editor.

## Aliases

If you use the command line a lot, you end up running the same couple commands over and over again. Sometimes it can help to shorten those commands and this is where aliases come in. You can add these directly to your `~/.bashrc` file. They look like this:

```sh
alias short='longer command --here'
```

Here are some examples from my aliases (feel free to steal them!):

```sh
alias d='docker'
alias di='docker images'
alias da='docker ps -a'
alias drma='docker rm -f $(docker ps -q)'

alias ip="dig +short myip.opendns.com @resolver1.opendns.com"
alias ipl="hostname -I | cut -d' ' -f1"
alias ips="ifconfig -a | grep -o 'inet6\? \(addr:\)\?\s\?\(\(\([0-9]\+\.\)\{3\}[0-9]\+\)\|[a-fA-F0-9:]\+\)' | awk '{ sub(/inet6? (addr:)? ?/, \"\"); print }'"

alias c="code ."

alias be="bundle exec"
```

Now you're looking good and your more productive to boot! There are lots of customizations you can do to customize your command prompt! I have some git status tools in mine. For more information, check out the [Awesome Bash](https://github.com/awesome-lists/awesome-bash) list or try googling "awesome zsh" or "awesome fish shell" for the other lists for other shells! 

Happy hacking!