Lesson 17: Shell Configuration

Goal: Customize your terminal with aliases, environment variables, prompt, and shell configuration files.


Table of Contents

  1. Shell Types — bash vs zsh
  2. Configuration Files
  3. Aliases
  4. Environment Variables
  5. The PATH Variable
  6. Prompt Customization (PS1)
  7. Useful .bashrc Configuration
  8. Exercises

Shell Types — bash vs zsh

Check your current shell

echo $SHELL
# Output: /bin/bash or /bin/zsh

Bash (Bourne Again Shell)

  • Default on most Linux distributions
  • Stable, well-documented, universal
  • Config files: ~/.bashrc, ~/.bash_profile

Zsh (Z Shell)

  • Default on macOS, popular on Linux
  • Better autocompletion and features
  • Config file: ~/.zshrc
  • Extensible with Oh My Zsh

Switch shells

# Install zsh
sudo apt install zsh

# Change your default shell
chsh -s /bin/zsh

# Log out and back in for the change to take effect

Configuration Files

Load order for bash

Login shell (SSH, terminal login):
  1. /etc/profile          (system-wide)
  2. ~/.bash_profile       (user, OR ~/.bash_login OR ~/.profile)
  3. ~/.bashrc             (usually sourced from .bash_profile)

Non-login shell (new terminal window):
  1. ~/.bashrc

The key file: ~/.bashrc

# View your bashrc
cat ~/.bashrc

# Edit it
nano ~/.bashrc

# After editing, reload it
source ~/.bashrc
# or shorthand
. ~/.bashrc

Aliases

Aliases create shortcuts for long or common commands.

Create temporary aliases

# Only lasts for current session
alias ll='ls -la'
alias gs='git status'

Create permanent aliases

Add them to ~/.bashrc:

# Open bashrc
nano ~/.bashrc

# Add at the end:
alias ll='ls -la'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias ...='cd ../..'
alias gs='git status'
alias ga='git add .'
alias gc='git commit -m'
alias gp='git push'
alias update='sudo apt update && sudo apt upgrade -y'
alias myip='curl -s ifconfig.me'
alias ports='ss -tulnp'
alias df='df -h'
alias du='du -h'
alias free='free -h'
alias mkdir='mkdir -pv'
alias grep='grep --color=auto'
# Reload
source ~/.bashrc

List and remove aliases

# Show all aliases
alias

# Remove an alias for current session
unalias ll

Aliases with arguments — use functions

Aliases can't take arguments. Use functions instead:

# Add to ~/.bashrc

# Create directory and enter it
mkcd() {
    mkdir -p "$1" && cd "$1"
}

# Quick find
qfind() {
    find . -name "*$1*"
}

# Extract any archive
extract() {
    if [ -f "$1" ]; then
        case "$1" in
            *.tar.bz2) tar xjf "$1" ;;
            *.tar.gz)  tar xzf "$1" ;;
            *.tar.xz)  tar xJf "$1" ;;
            *.bz2)     bunzip2 "$1" ;;
            *.gz)      gunzip "$1" ;;
            *.tar)     tar xf "$1" ;;
            *.zip)     unzip "$1" ;;
            *.7z)      7z x "$1" ;;
            *)         echo "'$1' cannot be extracted" ;;
        esac
    else
        echo "'$1' is not a file"
    fi
}

Environment Variables

View variables

# All environment variables
env

# Specific variable
echo $HOME
echo $USER
echo $SHELL
echo $PATH
echo $EDITOR
echo $LANG

Set variables

# For current session only
export MY_VAR="hello"
echo $MY_VAR

# Permanent — add to ~/.bashrc
echo 'export EDITOR="nano"' >> ~/.bashrc
echo 'export VISUAL="nano"' >> ~/.bashrc
source ~/.bashrc

Common variables to set

# Add to ~/.bashrc

# Default editor
export EDITOR="nano"
export VISUAL="nano"

# Language
export LANG="en_US.UTF-8"

# History settings
export HISTSIZE=10000
export HISTFILESIZE=20000
export HISTCONTROL=ignoreboth:erasedups

# Colored man pages
export LESS_TERMCAP_mb=$'\e[1;32m'
export LESS_TERMCAP_md=$'\e[1;32m'
export LESS_TERMCAP_me=$'\e[0m'
export LESS_TERMCAP_se=$'\e[0m'
export LESS_TERMCAP_so=$'\e[01;33m'
export LESS_TERMCAP_ue=$'\e[0m'
export LESS_TERMCAP_us=$'\e[1;4;31m'

Unset a variable

unset MY_VAR

The PATH Variable

PATH tells the shell where to find executables.

View your PATH

echo $PATH
# Output: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

# Show it nicely
echo $PATH | tr ':' '\n'

How PATH works

When you type ls, the shell searches these directories in order:

  1. /usr/local/bin/ls — not found
  2. /usr/bin/ls — found! Execute this.

Add to PATH

# Temporary
export PATH="$HOME/bin:$PATH"

# Permanent — add to ~/.bashrc
echo 'export PATH="$HOME/.local/bin:$HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Practical: Add custom scripts to PATH

# 1. Create a bin directory
mkdir -p ~/bin

# 2. Create a script
cat > ~/bin/sysinfo << 'EOF'
#!/bin/bash
echo "=== System Info ==="
echo "Host: $(hostname)"
echo "User: $USER"
echo "Date: $(date)"
echo "Uptime: $(uptime -p)"
echo "Memory: $(free -h | awk '/Mem/ {print $3 "/" $2}')"
echo "Disk: $(df -h / | awk 'NR==2 {print $3 "/" $2 " (" $5 ")"}')"
EOF

# 3. Make it executable
chmod +x ~/bin/sysinfo

# 4. Ensure ~/bin is in PATH (add to .bashrc if not)
export PATH="$HOME/bin:$PATH"

# 5. Run from anywhere
sysinfo

Prompt Customization (PS1)

The prompt is controlled by the PS1 variable.

Escape sequences for PS1

Code Meaning
\u Username
\h Hostname
\w Working directory (full)
\W Working directory (basename)
\d Date
\t Time (24h)
\T Time (12h)
\n Newline
\$ $ for user, # for root

Examples

# Simple: user@host:dir$
PS1='\u@\h:\w\$ '

# With colors
PS1='\[\e[1;32m\]\u@\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ '

# Minimal
PS1='\W \$ '

# With date and time
PS1='[\d \t] \u@\h:\w\$ '

# Two-line prompt
PS1='\[\e[1;32m\]\u@\h\[\e[0m\] \[\e[1;34m\]\w\[\e[0m\]\n\$ '

Make it permanent

# Add to ~/.bashrc
echo "PS1='\[\e[1;32m\]\u@\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ '" >> ~/.bashrc
source ~/.bashrc

Useful .bashrc Configuration

Here's a complete, well-commented .bashrc addition:

# Append this to your ~/.bashrc

# ─── History ──────────────────────────────────────
HISTSIZE=10000
HISTFILESIZE=20000
HISTCONTROL=ignoreboth:erasedups
shopt -s histappend

# ─── Navigation ──────────────────────────────────
shopt -s cdspell         # autocorrect cd typos
shopt -s autocd          # type directory name to cd into it
shopt -s dirspell        # autocorrect directory names

# ─── Aliases ─────────────────────────────────────
alias ll='ls -la --color=auto'
alias la='ls -A --color=auto'
alias ls='ls --color=auto'
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias grep='grep --color=auto'
alias df='df -h'
alias du='du -h'
alias free='free -h'
alias mkdir='mkdir -pv'

# Git shortcuts
alias gs='git status'
alias ga='git add'
alias gc='git commit -m'
alias gp='git push'
alias gl='git log --oneline -10'
alias gd='git diff'

# System
alias update='sudo apt update && sudo apt upgrade -y'
alias myip='curl -s ifconfig.me && echo'
alias ports='ss -tulnp'

# ─── Functions ───────────────────────────────────
# Create directory and cd into it
mkcd() { mkdir -p "$1" && cd "$1"; }

# Quick backup of a file
bak() { cp "$1" "$1.bak.$(date +%Y%m%d-%H%M%S)"; }

# ─── Prompt ──────────────────────────────────────
PS1='\[\e[1;32m\]\u@\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ '

# ─── Path ────────────────────────────────────────
export PATH="$HOME/.local/bin:$HOME/bin:$PATH"
export EDITOR="nano"

Apply changes

source ~/.bashrc

Exercises

Exercise 1: Create aliases

# 1. Create a temporary alias
alias hello='echo "Hello, $USER!"'
hello

# 2. Add permanent aliases to .bashrc
echo "alias cls='clear'" >> ~/.bashrc
echo "alias h='history 20'" >> ~/.bashrc
source ~/.bashrc

# 3. Test them
cls
h

Exercise 2: Environment variables

# 1. Set a custom variable
export PROJECT_DIR="$HOME/projects"
echo $PROJECT_DIR

# 2. Check your default editor
echo $EDITOR

# 3. Set nano as default editor (permanent)
echo 'export EDITOR="nano"' >> ~/.bashrc
source ~/.bashrc
echo $EDITOR

Exercise 3: Custom script in PATH

# 1. Create ~/bin
mkdir -p ~/bin

# 2. Create a weather script
cat > ~/bin/weather << 'EOF'
#!/bin/bash
curl -s "wttr.in/${1:-Berlin}?format=3"
EOF
chmod +x ~/bin/weather

# 3. Add to PATH if needed
export PATH="$HOME/bin:$PATH"

# 4. Use it
weather
weather London

Key Takeaways

  • ~/.bashrc — your main configuration file
  • source ~/.bashrc — reload after changes
  • alias name='command' — create shortcuts
  • export VAR="value" — set environment variables
  • PATH — tells the shell where to find programs
  • PS1 — customize your prompt
  • Functions for aliases that need arguments
  • Always back up .bashrc before major changes: cp ~/.bashrc ~/.bashrc.bak

Next Lesson: Lesson 18: Networking & SSH →