Now that we have a better handle on terminal commands and environment variables, we can start looking at one of the funner bits of the terminal: customizing it!

This will mostly be an overview of the ways you can customize the terminal and some options I know of in each category. I encourage you to explore a bit, as a terminal that's fun to look at and use is a great way to encourage using it more!

The shell

Most Linux distributions use the bash shell program by default, though not all - zsh is another choice you may have. You can find out which one your system uses from the SHELL environment variable:

bsh ❯ echo $SHELL
/bin/bash

Some of what I describe in this section may be bash-specific, so if your shell is zsh or something else, you may need to do some searching if something I have here doesn't work and I haven't noted the alternative.

In general, bash is the safest shell to assume that another developer will be using, and most shell scripts you find on the internet are bash-compatible. That said, there's a small but enthusiastic community for many alternative shells, such as: dash, fish, nushell, Powershell for Windows, elvish...

The .bashrc file

For bash, customization mainly happens in a specific file that bash loads when it starts, located at ~/.bashrc by default. This file lets you execute commands when you start your shell, and that includes things like setting up environment variables, defining functions, and other preferences.

We'll talk about some of those features more in-depth in the next chapter and focus this chapter on how to add individualized touches.

The prompt

Similar to how questions on a survey or creative writing scenarios implicitly request your input, the shell also requests your input - both in the form of a prompt.

The shell prompt is the stuff that shows automatically every time you have input control in the terminal. All of the below prompts have shown up in this book so far:

# this prompt says the user, the machine name, and the directory
[stephen@virtualbox ~]

# this prompt says the directory on its own line, then a line break,
# then says which shell I'm using, followed by a prompt separator
~
bsh ❯

# this prompt says my directory (on Windows) followed by a prompt separator
C:\Users\sthar>

In bash, this prompt is decided by the variable PS1, short for "prompt string 1". You can build the first prompt here with this string:

export PS1="[\u@\h \W]\$ "

This uses some prompt string shorthands (/\u, /\h, and /\W) to show the user, the "host name" of the machine, and the working directory.

For a long time, I had a custom prompt I made myself, with lots of colors and meta-information, and a mysterious WAIT_WHAT_STRING I can't remember the purpose of. You can build your own and do something like I did, assigning the final string to the environment variable PS1:

build_prompt() {
	# find out if we're running a virtualenv
    if [ -z ${VIRTUAL_ENV+x} ]; then # VIRTUAL_ENV is unset
        if [ $(pwd) == ~ ]; then
            echo "No virtual environment set here"
        fi
        VIRTUAL_ENV_PROMPT_STR=""
    else
        VIRTUAL_ENV_PROMPT_STR=" ($(basename `echo ${VIRTUAL_ENV}`))"
        echo "Currently in ${VIRTUAL_ENV_PROMPT_STR:2:${#VIRTUAL_ENV_PROMPT_STR}-3}"
    fi

    # now build the string
    DATETIME_STRING="\[$(tput setaf 6)\]\d \[$(tput setaf 4)\]"
    VENV_STRING="\[$(tput setaf 3)\]${VIRTUAL_ENV_PROMPT_STR}"
    CURRENT_DIR_STRING="\[$(tput setaf 1)\]\w"
    USER_STRING="\[$(tput setaf 2)\]\u"
    WAIT_WHAT_STRING="\[$(tput sgr0)\]"
    GIT_STRING="\[$(tput setaf 7)\]$(__git_ps1)"

    PS1="${DATETIME_STRING}\t ${VENV_STRING} ${CURRENT_DIR_STRING} ${GIT_STRING}\n    ${USER_STRING} >${WAIT_WHAT_STRING}"
}

But that's pretty gnarly. Nowadays, I just use Starship for something easy and pretty. You can find a list of some other ready-to-go prompts in this "awesome bash" repository.

The terminal emulator

The last piece for this chapter, and for some developers the most important, is the terminal emulator itself. There are a few dimensions worth considering here:

  • appearance
  • speed
  • customizability

I personally just use Windows Terminal on my home machines and Alacritty if I have to work on MacOS. There are loads of other options, though, such as this list of terminal emulators on another Github repository.

Summary