DEV Community

Cover image for Developer Tools: The Command Line
Conlin Durbin
Conlin Durbin

Posted on

Developer Tools: The Command Line

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 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. 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 (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 (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, 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 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. I am thinking about switching to this in the future to play around with it.

Todd likes fish and shared in the comments:

+1 for fish. I've been using it for almost 2 years now. I'm a big big fan. There is also oh my fish for package management and modification.

xonsh

xonsh 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 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 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:

#!/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\]"

Enter fullscreen mode Exit fullscreen mode

This gives us a bunch of colors to work with. Just for the record, those colors are described in ANSI escape codes.

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


# ^ 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;
Enter fullscreen mode Exit fullscreen mode

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:

# end of ~/.bashrc

source ~/.bash_prompt
Enter fullscreen mode Exit fullscreen mode

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:

alias short='longer command --here'
Enter fullscreen mode Exit fullscreen mode

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

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"
Enter fullscreen mode Exit fullscreen mode

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 list or try googling "awesome zsh" or "awesome fish shell" for the other lists for other shells!

Happy hacking!

Top comments (4)

Collapse
 
moopet profile image
Ben Sinclair

Seeing a variable with a name like wdnhrd makes me uncomfortable!
I'm not sure why, but it seems to go Java > C > shell in terms of how descriptive a programer is, from overlyLoquaciousAndErudite to txt_spk_cntr to wtfbbq1.

Collapse
 
eidsonator profile image
Todd Eidson

+1 for fish. I've been using it for almost 2 years now. I'm a big big fan. There is also oh my fish for package management and modification.

Collapse
 
neurotictumbleweed profile image
Andrew

The "Gnome Shell" is the graphical shell of the Gnome desktop environment and isn't a terminal emulator.

Collapse
 
wuz profile image
Conlin Durbin

Good catch! That should have been GNOME Terminal.