Day 2 - Shell Fundamentals (Bash)

2025-09-227 min read

linuxbashshellterminalpathquotinghistory

Day2 Terminal

This lesson covers the shell skills used every day: how commands are built, how quoting changes meaning, how PATH finds programs, and how to get help quickly. Examples assume the Bash shell.

What is a shell?

A shell is a program that reads what a user types and runs it. Bash is the default shell on many systems. Check the current shell with echo $SHELL.

Prerequisites

Anatomy of a command

Commands usually have four parts.

text
program  -s  --long  argument1  argument2
  • program: the tool to run, for example ls or cat
  • options: short options start with a single dash, long options start with two dashes
  • arguments: items the program works on, such as files or directories

Examples:

bash
ls -la               # list files with details, show hidden files
mkdir projects && cd projects
cp /etc/hosts ./hosts.backup
End of options

When a file name begins with a dash, stop option parsing with -- to avoid surprises, for example rm -- -weird-name or grep -- "-pattern" file.txt.

Built-in and external commands

Some commands are Bash built-ins. Others are external programs stored on disk. Use type or command -V to check.

bash
type cd        # builtin
command -V ls  # usually /usr/bin/ls
which ls       # path of an external program

Built-ins provide help with help <name>.

bash
help cd
help alias

External programs provide manuals and inline help.

bash
man ls
ls --help | less

Quoting rules that matter

Quoting changes how Bash parses text.

  • Unquoted text allows globbing and word splitting; spaces break words; wildcards expand
  • Single quotes '...' keep text exact; nothing inside changes
  • Double quotes "..." allow variable expansion and command substitution while protecting spaces
  • Backslash \ escapes the next character only

Examples:

bash
# unquoted: splits on spaces and expands globs
printf %s\n *

# single quotes: literal text
printf '%s\n' *

# double quotes: expands variables but keeps spaces
name="Majd Banat"
echo "Hello $name"

# escape one character
echo A\ B
Safe habit

Quote variables by default: "$var". This avoids bugs when values contain spaces or newlines.

Command substitution

Use $(...) to insert the output of one command into another.

bash
# show kernel version inside a sentence
echo "Kernel: $(uname -r)"

# save the current date in a variable
now=$(date +%F)
echo "Today is $now"

# nested example
echo "User $(id -un) on host $(hostname)"

Avoid backticks `...` because they are hard to nest and read.

Globbing and expansions

Bash expands patterns before running the program.

bash
# wildcards
ls *.log
ls file?.txt

# character classes
ls report_[AB].pdf

# brace expansion creates many words quickly
mkdir -p logs/{nginx,app,db}
cp -v config.{example,backup}

# tilde expansion to the home directory
cd ~

To search for a literal asterisk or question mark, quote the pattern.

bash
grep "*.log" notes.txt
Be careful with rm

Never run rm -rf * without confirming the current directory. Check with pwd, then run ls first to preview what will be removed. Add -i for interactive prompts when unsure.

PATH and how Bash finds programs

When a program name is typed, Bash searches the directories in the PATH variable from left to right.

bash
echo $PATH | tr ':' '\n'

Create a personal ~/bin directory and add it to the front of PATH so custom tools take priority.

bash
mkdir -p "$HOME/bin"
# add once to the end of ~/.bashrc
printf '
# add personal bin to PATH
export PATH="$HOME/bin:$PATH"
' >> "$HOME/.bashrc"
# reload the current shell
source ~/.bashrc

Create a small script and run it from anywhere.

bash
cat > "$HOME/bin/hi" <<'EOF'
#!/usr/bin/env bash
echo "Hi from $(hostname)"
EOF
chmod +x "$HOME/bin/hi"
hi
Login shell and interactive shell

Some systems load ~/.profile for login shells and ~/.bashrc for interactive shells. If PATH changes do not persist after login, add the same export to both files.

Variables and environment

Set a shell variable with name=value. Export it when child processes should see it.

bash
color=blue
export color
# or in one line
export color=blue

printenv | grep -i color || true

Persistent settings belong in ~/.bashrc so they load in new terminals.

bash
printf '
# custom color for demo
export COLOR_PREFERENCE="blue"
' >> ~/.bashrc
source ~/.bashrc
No spaces around =

Do not write name = value. Bash will treat it as a command with three arguments. Use name=value with no spaces.

Aliases and small functions

Aliases shorten common commands and small functions automate simple tasks. Keep them in ~/.bashrc.

bash
cat >> ~/.bashrc <<'EOF'
# helpful aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
# function with one argument
mkcd() { mkdir -p "$1" && cd "$1"; }
EOF
source ~/.bashrc

Test them.

bash
ll
mkcd ~/playground/day2
pwd

Bypass an alias with a leading backslash.

bash
\ls -1

History and faster editing

History and completion speed up work.

  • Up and Down: browse previous commands
  • Ctrl R: search history; type a few letters and press Enter to run the match
  • Tab: complete commands and paths; press Tab twice to see choices

Add timestamps to history entries.

bash
printf '
HISTTIMEFORMAT="%F %T "
' >> ~/.bashrc
source ~/.bashrc
history | tail -5
Repeat the last command with sudo

sudo !! repeats the previous command with sudo. Useful after a permission denied error.

Interrupt a program

If a program hangs, press Ctrl C to send SIGINT. If it still hangs, close the terminal or use kill from another terminal. Process control is covered later in the series.

Redirection and pipes

Input and output redirection and pipes are core building blocks.

bash
# send output to a file (overwrite or append)
ls -la > listing.txt
ls -la >> listing.txt

# read input from a file
wc -l < listing.txt

# pipe output of one command into another
ps aux | grep ssh | grep -v grep
Small workflow

Chain commands with && when the second should run only if the first succeeds. Use ; to run commands regardless of success.

bash
mkdir -p ~/playground/day2 && cd ~/playground/day2
curl -s https://example.com | wc -c

Common mistakes and quick fixes

  • Quote variables: prefer "$var"
  • Avoid editing system files as root unless required; prefer sudo for single commands
  • Check the source of a command with type -a <name> to see aliases and paths
  • Read error messages; Bash often explains what went wrong
  • Use -- to stop option parsing when a file name starts with a dash

Up next: Day 3 - Navigating the Filesystem and FHS

Day 3 focuses on the filesystem and the Linux directory layout. Learn fast navigation techniques and safe delete habits.