Lesson 17: Shell Configuration
Goal: Customize your terminal with aliases, environment variables, prompt, and shell configuration files.
Table of Contents
- Shell Types — bash vs zsh
- Configuration Files
- Aliases
- Environment Variables
- The PATH Variable
- Prompt Customization (PS1)
- Useful .bashrc Configuration
- 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:
/usr/local/bin/ls— not found/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 filesource ~/.bashrc— reload after changesalias name='command'— create shortcutsexport VAR="value"— set environment variablesPATH— tells the shell where to find programsPS1— customize your prompt- Functions for aliases that need arguments
- Always back up
.bashrcbefore major changes:cp ~/.bashrc ~/.bashrc.bak
Next Lesson: Lesson 18: Networking & SSH →