Computing Foundations › The Command Line › Day 8
Hands-on lab — Day 8: Meet the Terminal: Shells, Prompts, and Commands
- ← Back to the Day 8 lesson
- Open the hands-on files on GitHub — clone or download them from the public labs repository
- Local path in your clone:
labs/sections/computing-foundations/day-008-meet-the-terminal-shells-prompts-and/
Commands
Setup
cd labs/sections/computing-foundations/day-008-meet-the-terminal-shells-prompts-and Run
bash examples/shell_tour.sh
bash starter/shell_tour.sh Test
bash tests/run_tests.sh File tree
examples/shell_tour.sh expected-output/FIELDS.md expected-output/sample-macos.txt metadata.yml README.md requirements/README.md security.md starter/shell_tour.sh starter/shell-session-worksheet.md tests/run_tests.sh troubleshooting.md
Lab README
Day 008 lab — Your First Shell Session
Lesson
- Lesson title: Meet the Terminal: Shells, Prompts, and Commands
- Day number: 8 of 365
- Lesson article: https://ai-roadmap-365.github.io/day-008-meet-the-terminal-shells-prompts-and
- Lab files: everything you need is in this directory — follow “How to run” below.
- Browse the course locally: from the repository root, this lab also appears in the course website at
/labs/day-008-meet-the-terminal-shells-prompts-andwhen the site is running.
Purpose
Day 8's lesson explains what a terminal, a shell, and a command are. This lab
makes it concrete: you run a short tour of your own shell that reveals which
shell is running, what your prompt string is, and what a handful of everyday
commands (pwd, echo, date, whoami, history, type) actually print.
Then you fill in a worksheet describing your session in your own words.
Learning objectives
- Discover which shell you are running and your default shell (
echo $0,echo $SHELL,ps -p $$). - See your raw prompt string (
echo "$PS1") and understand what it is. - Run and read the output of
pwd,echo,date, andwhoami. - Recall recent commands with
history | tailand identify a command withtype. - Complete a shell script by filling in five well-specified exercises, then verify it with an automated test.
Prerequisites
- The Day 8 lesson (read it first — it explains every term this lab shows you).
- A terminal: Terminal.app (macOS), any terminal (Linux), or PowerShell/WSL (Windows).
- No programming experience required; every command is given and explained.
Supported operating systems
- macOS — fully supported (tested on macOS with Apple Silicon, default shell zsh).
- Linux — fully supported (any distribution with bash and standard utilities).
- Windows — run the scripts unmodified inside WSL, or type the individual commands from the lesson's hands-on section in PowerShell where equivalents exist.
Hardware requirements
Any computer made in roughly the last 15 years. The lab only reads session information; it needs no minimum RAM, disk, or GPU.
Required software
bash(3.2 or newer — preinstalled on macOS and Linux).- Standard OS utilities only:
ps,pwd,echo,date,whoami,sed,tail. All preinstalled.
Free and open-source options
Everything in this lab is free: bash and every command used are open-source or ship with your OS. No account, API key, or purchase is needed.
Installation
None. Clone the repository (or copy this directory) and you are ready:
cd labs/sections/computing-foundations/day-008-meet-the-terminal-shells-prompts-and
File structure
day-008-meet-the-terminal-shells-prompts-and/
├── README.md ← you are here
├── metadata.yml ← machine-readable lab metadata
├── starter/
│ ├── shell_tour.sh ← YOUR working file (5 exercises)
│ └── shell-session-worksheet.md ← worksheet for the practice assignment
├── examples/
│ └── shell_tour.sh ← completed reference implementation
├── tests/
│ └── run_tests.sh ← automated checks
├── expected-output/
│ ├── sample-macos.txt ← real captured run (macOS, zsh default)
│ └── FIELDS.md ← required sections on every platform
├── requirements/
│ └── README.md ← dependency statement (none beyond the OS)
├── troubleshooting.md
└── security.md
How to run
From this directory:
## 1. See the finished result first
bash examples/shell_tour.sh
## 2. Your task: complete the five exercises in the starter, then run it
bash starter/shell_tour.sh
## 3. Check your work
bash tests/run_tests.sh
What the commands do
bash examples/shell_tour.sh— runs the reference tour: prints the running shell (echo $0), your default shell (echo $SHELL), the shell process (ps -p $$), your prompt string (echo "$PS1"), thenpwd,echo hello,date,whoami, ahistory | tailsample, andtype echo.bash starter/shell_tour.sh— the same skeleton with five values set tounknown; each exercise comment names the exact command to use. Edit the file in any text editor and replace eachunknownassignment with the command in$(...)form.bash tests/run_tests.sh— runs both scripts and checks: exit code 0, the tour header/footer, every required section, thatecho helloprintshelloandtype echoreports a shell builtin; and (once your starter has nounknownleft) that the five exercise fields hold real values.
Expected output
See expected-output/sample-macos.txt — a
real captured run. A shortened view:
=== Shell Tour ===
Generated on: 2026-07-12
--- Which shell am I running? ---
Current shell (echo $0): examples/shell_tour.sh
Default shell (echo $SHELL): /bin/zsh
Shell process (ps -p $$):
PID TTY TIME CMD
12117 ?? 0:00.00 bash examples/shell_tour.sh
...
Echo demo (echo hello): hello
Date (date): Sun Jul 12 13:32:42 IST 2026
User (whoami): you
...
type echo: echo is a shell builtin
=== End of tour ===
Your values will differ — that is the point. Note that echo $0 inside a script
prints the script's name; run echo $0 directly in your terminal to see
your interactive shell (e.g. -zsh). expected-output/FIELDS.md
lists exactly which sections must appear on every platform.
Validation steps
- Run
bash starter/shell_tour.sh— it must exit without errors. - Confirm no exercise line reads
unknown(the five fields you filled in). - Confirm the tour prints your shell, your default shell,
pwd,date, andwhoami. - Run the tests (next section) — all checks must pass.
Tests
bash tests/run_tests.sh
Expected final line: 35 checks, 0 failure(s). (20 strict checks against the
reference tour, and 15 structural checks against your starter — which become 20
strict checks once you have replaced every unknown). The command exits 0 on
success and non-zero on any failure, so it can run in CI.
Cleanup
Nothing to clean up: the scripts only read session information and write nothing
outside their own console output. To reset your work, restore the starter file
from git: git checkout -- starter/shell_tour.sh.
Troubleshooting
See troubleshooting.md for the full list (empty $PS1,
empty history, $0 showing the script name, WSL notes).
Security notes
See security.md. Short version: the scripts run no network calls, need no elevated privileges, and expose only local session facts — but a shell profile is mildly identifying, so think before pasting it publicly.
Extension exercises
- Run
echo $0andecho "$PS1"directly in your interactive terminal (not through the script) and compare the values with the script's output — explain the difference in one sentence. - Start a different shell by hand (
bash, then laterexit) and re-runecho $0inside it; confirm$SHELLis unchanged while$0now names the shell you started. - Open
man ls, read the descriptions of-land-a, quit withq, then runls -la /and confirm you can label the command, options, and argument.
Navigation
- Previous day: Day 7 — the final lesson of Week 1.
- Next day: Day 9 — the next lesson of Week 2 (to be written).
Expected output
FIELDS.md
# Required tour sections (all platforms)
A correct run of `shell_tour.sh` prints, in order, these labelled sections:
1. `=== Shell Tour ===`
2. `Generated on: YYYY-MM-DD`
3. `Current shell (echo $0): <shell or script name>`
4. `Default shell (echo $SHELL): <path, e.g. /bin/zsh or /bin/bash>`
5. `Shell process (ps -p $$):` followed by the current shell's process row
6. `Prompt string (echo "$PS1"): <template, or an "empty" note in non-interactive runs>`
7. `Working directory (pwd): <an absolute path>`
8. `Echo demo (echo hello): hello`
9. `Date (date): <current date and time>`
10. `User (whoami): <your username>`
11. `Recent command history (history | tail)` section (may be empty in a script)
12. `type echo: echo is a shell builtin`
13. `=== End of tour ===`
`sample-macos.txt` in this directory is a real captured run (macOS, Apple
Silicon, zsh as the default shell, 2026-07-12).
## Platform and context notes (real, not fabricated)
- **`echo $0` inside a script prints the script's path** (e.g.
`examples/shell_tour.sh`), because `$0` is the name of the *program running
now* — which, for a script, is the script. Run `echo $0` **directly in your
interactive terminal** and it prints your shell instead, such as `-zsh` or
`bash`. Both are correct; they answer slightly different questions.
- **`$PS1` is usually empty in a non-interactive script**, so the tour prints a
note rather than a value. Run `echo "$PS1"` in your interactive shell to see
the real prompt template (for example `%n@%m %1~ %#` in zsh).
- **`history | tail` is often empty inside a script**, because history is a
feature of interactive shells. Run `history | tail` directly in your terminal
to see your logged commands.
- **Linux vs macOS:** the shape is identical. `ps -p $$` formats its columns
slightly differently, `date` follows your locale, and if your default shell is
bash the `$SHELL` line reads `/bin/bash`. No field is fabricated here; only the
exact strings differ by machine.
sample-macos.txt
=== Shell Tour ===
Generated on: 2026-07-12
--- Which shell am I running? ---
Current shell (echo $0): examples/shell_tour.sh
Default shell (echo $SHELL): /bin/zsh
Shell process (ps -p $$):
PID TTY TIME CMD
12117 ?? 0:00.00 bash examples/shell_tour.sh
--- What does my prompt look like? ---
Prompt string (echo "$PS1"): (empty in this non-interactive run — try it in your interactive shell)
--- A handful of everyday commands ---
Working directory (pwd): <repo>/labs/sections/computing-foundations/day-008-meet-the-terminal-shells-prompts-and
Echo demo (echo hello): hello
Date (date): Sun Jul 12 13:32:42 IST 2026
User (whoami): you
--- Recent command history (history | tail) ---
(no history in this non-interactive run — run 'history | tail' in your terminal)
--- What kind of thing is 'echo'? ---
type echo: echo is a shell builtin
=== End of tour ===
Source files
examples/shell_tour.sh (2230 bytes)
#!/usr/bin/env bash
# Day 008 lab — completed reference implementation: a guided tour of your shell.
#
# Prints, in clearly labelled sections: which shell is running, your default
# shell, the shell process, your prompt string, and the output of a handful of
# everyday commands (pwd, echo, date, whoami, history, type). Every command is
# read-only — it inspects your session and changes nothing.
#
# Works in bash and zsh on macOS and Linux. Run it with:
# bash examples/shell_tour.sh
set -u
echo "=== Shell Tour ==="
echo "Generated on: $(date '+%Y-%m-%d')"
echo
echo "--- Which shell am I running? ---"
# $0 is the name of the shell (or script) currently running.
echo "Current shell (echo \$0): $0"
# $SHELL is your DEFAULT login shell, which may differ from the one running now.
echo "Default shell (echo \$SHELL): ${SHELL:-unknown}"
# ps -p $$ shows the process of the current shell ($$ is its process id).
echo "Shell process (ps -p \$\$):"
ps -p $$ | sed 's/^/ /'
echo
echo "--- What does my prompt look like? ---"
# PS1 is the prompt-string template. In a non-interactive script it is often
# empty; run 'echo \"\$PS1\"' directly in your interactive shell to see it.
if [ -n "${PS1:-}" ]; then
echo "Prompt string (echo \"\$PS1\"): ${PS1}"
else
echo "Prompt string (echo \"\$PS1\"): (empty in this non-interactive run — try it in your interactive shell)"
fi
echo
echo "--- A handful of everyday commands ---"
echo "Working directory (pwd): $(pwd)"
echo "Echo demo (echo hello): $(echo hello)"
echo "Date (date): $(date)"
echo "User (whoami): $(whoami)"
echo
echo "--- Recent command history (history | tail) ---"
# 'history' is a shell built-in; in a non-interactive script the list may be
# empty. This is expected — the point is that your INTERACTIVE shell records it.
hist_output="$(history 2>/dev/null | tail || true)"
if [ -n "${hist_output}" ]; then
echo "${hist_output}" | sed 's/^/ /'
else
echo " (no history in this non-interactive run — run 'history | tail' in your terminal)"
fi
echo
echo "--- What kind of thing is 'echo'? ---"
# 'type' tells you whether a name is a built-in, a program on disk, or an alias.
echo "type echo: $(type echo)"
echo
echo "=== End of tour ==="
metadata.yml (575 bytes)
lesson_id: D008
day: 8
kind: command-line-inspection
languages: [bash]
setup_commands:
- cd labs/sections/computing-foundations/day-008-meet-the-terminal-shells-prompts-and
run_commands:
- bash examples/shell_tour.sh
- bash starter/shell_tour.sh
test_commands:
- bash tests/run_tests.sh
cleanup_commands:
- 'git checkout -- starter/shell_tour.sh # optional: reset your work'
requires_network: false
requires_api_key: false
estimated_minutes: 30
last_executed: '2026-07-12'
executed_on: 'macOS (Apple Silicon), bash tests/run_tests.sh → 35 checks, 0 failure(s).'
requirements/README.md (558 bytes)
# Dependencies — Day 008 lab
**None beyond a POSIX shell.** This lab intentionally has zero installable
dependencies:
- `bash` ≥ 3.2 (preinstalled on macOS and every mainstream Linux distribution)
- Standard OS utilities: `ps`, `pwd`, `echo`, `date`, `whoami`, `sed`, `tail`,
and the shell built-ins `history` and `type` — all part of the base system.
There is deliberately no `requirements.txt`/`package.json` here; a first
terminal lab must run on a factory-fresh machine. Later labs declare their
Python or Node dependencies in this directory.
starter/shell_tour.sh (2389 bytes)
#!/usr/bin/env bash
# Day 008 lab — YOUR shell tour.
#
# This starter already prints the section headers and the demonstration lines
# (the shell process, your prompt string, a history sample, and 'type echo').
# Your job is the five numbered exercises below: replace each `unknown` with the
# single command shown in the comment, wrapped in $(...) so its output is
# captured. The finished reference version is in examples/shell_tour.sh — try it
# yourself first, then run this, then run the tests.
set -u
echo "=== Shell Tour ==="
echo "Generated on: $(date '+%Y-%m-%d')"
echo
echo "--- Which shell am I running? ---"
# Exercise 1: set current_shell using the command: echo $0
# ($0 is the name of the shell or script running right now.)
current_shell="unknown"
# Exercise 2: set default_shell using the command: echo $SHELL
# ($SHELL is your DEFAULT login shell — it may differ from the one running now.)
default_shell="unknown"
echo "Current shell (echo \$0): ${current_shell}"
echo "Default shell (echo \$SHELL): ${default_shell}"
echo "Shell process (ps -p \$\$):"
ps -p $$ | sed 's/^/ /'
echo
echo "--- What does my prompt look like? ---"
if [ -n "${PS1:-}" ]; then
echo "Prompt string (echo \"\$PS1\"): ${PS1}"
else
echo "Prompt string (echo \"\$PS1\"): (empty in this non-interactive run — try it in your interactive shell)"
fi
echo
echo "--- A handful of everyday commands ---"
# Exercise 3: set here using the command: pwd
# (pwd prints the working directory — the folder the shell is standing in.)
here="unknown"
# Exercise 4: set today using the command: date
# (date takes no options and no arguments; it prints the current date/time.)
today="unknown"
# Exercise 5: set me using the command: whoami
# (whoami prints your username — the identity your commands act as.)
me="unknown"
echo "Working directory (pwd): ${here}"
echo "Echo demo (echo hello): $(echo hello)"
echo "Date (date): ${today}"
echo "User (whoami): ${me}"
echo
echo "--- Recent command history (history | tail) ---"
hist_output="$(history 2>/dev/null | tail || true)"
if [ -n "${hist_output}" ]; then
echo "${hist_output}" | sed 's/^/ /'
else
echo " (no history in this non-interactive run — run 'history | tail' in your terminal)"
fi
echo
echo "--- What kind of thing is 'echo'? ---"
echo "type echo: $(type echo)"
echo
echo "=== End of tour ==="
starter/shell-session-worksheet.md (1617 bytes)
# My First Shell Session — Day 008 worksheet
Fill in every value from your own machine using the lab script or the individual
commands from the lesson's hands-on section. Keep this file — later lessons build
on your comfort at the prompt.
## My shell
| Field | Your value | Command you used |
| ----------------------------- | ---------- | ---------------- |
| Shell running right now | | `echo $0` (or `ps -p $$`) |
| My default login shell | | `echo $SHELL` |
| My raw prompt string (`$PS1`) | | `echo "$PS1"` |
## Three commands I ran
For each command, write the exact command you typed, exactly what it printed
(one line is fine), and a one-sentence explanation of what it did — naming which
parts were the command, options, and arguments.
| # | Exact command | What it printed | What it did (and its command / options / arguments) |
| - | ------------- | --------------- | --------------------------------------------------- |
| 1 | | | |
| 2 | | | |
| 3 | | | |
## How my command travelled through the read-eval-print loop
Write two or three sentences: name your shell, then trace one command you ran
from your keystrokes through the shell reading and parsing the line, finding and
running the program, printing the output, and the prompt returning.
## One thing that surprised me
One or two sentences.
tests/run_tests.sh (3248 bytes)
#!/usr/bin/env bash
# Tests for the Day 008 lab. Run from the lab directory:
# bash tests/run_tests.sh
#
# Verifies that the completed reference tour prints every required section with
# real (non-"unknown") values, and — if the learner has finished the starter —
# checks their version the same way.
set -u
lab_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
failures=0
checks=0
check() {
local label="$1" ok="$2"
checks=$((checks + 1))
if [ "${ok}" = "yes" ]; then
echo " ok: ${label}"
else
echo " FAIL: ${label}"
failures=$((failures + 1))
fi
}
run_tour_checks() {
local script="$1" strict="$2" output
echo "Testing ${script} ..."
if ! output="$(bash "${script}" 2>&1)"; then
check "script exits successfully" "no"
echo "${output}" | sed 's/^/ /'
return
fi
check "script exits successfully" "yes"
echo "${output}" | grep -q '^=== Shell Tour ===$' && check "prints tour header" "yes" || check "prints tour header" "no"
echo "${output}" | grep -q '^=== End of tour ===$' && check "prints tour footer" "yes" || check "prints tour footer" "no"
# Required labelled sections (the tour must show each of these).
for marker in \
"Current shell (echo \$0):" \
"Default shell (echo \$SHELL):" \
"Shell process (ps -p \$\$):" \
"Prompt string (echo \"\$PS1\"):" \
"Working directory (pwd):" \
"Echo demo (echo hello):" \
"Date (date):" \
"User (whoami):" \
"Recent command history (history | tail)" \
"type echo:"; do
if echo "${output}" | grep -qF "${marker}"; then
check "prints section '${marker}'" "yes"
else
check "prints section '${marker}'" "no"
fi
done
# The echo demo must actually print the word it echoed.
echo "${output}" | grep -qF "Echo demo (echo hello): hello" && check "echo hello prints 'hello'" "yes" || check "echo hello prints 'hello'" "no"
# 'type echo' should identify echo as a shell builtin.
echo "${output}" | grep -qi "echo is a shell builtin" && check "type echo reports a shell builtin" "yes" || check "type echo reports a shell builtin" "no"
if [ "${strict}" = "strict" ]; then
# In a finished tour, the five exercise fields must not read 'unknown'.
for field in \
"Current shell (echo \$0): unknown" \
"Default shell (echo \$SHELL): unknown" \
"Working directory (pwd): unknown" \
"Date (date): unknown" \
"User (whoami): unknown"; do
if echo "${output}" | grep -qF "${field}"; then
check "field is filled in, not 'unknown' (${field%%:*})" "no"
else
check "field is filled in, not 'unknown' (${field%%:*})" "yes"
fi
done
fi
}
run_tour_checks "${lab_dir}/examples/shell_tour.sh" strict
# The starter ships with 'unknown' values on purpose; once the learner has
# replaced them all, hold their script to the same strict standard.
if grep -q '="unknown"' "${lab_dir}/starter/shell_tour.sh"; then
echo "Note: starter/shell_tour.sh still has unfilled exercises — testing structure only."
run_tour_checks "${lab_dir}/starter/shell_tour.sh" lenient
else
run_tour_checks "${lab_dir}/starter/shell_tour.sh" strict
fi
echo
echo "${checks} checks, ${failures} failure(s)."
[ "${failures}" -eq 0 ]
Troubleshooting
Troubleshooting — Day 008 lab
echo $0 prints the script name, not my shell
That is correct. $0 is the name of the program running right now; inside a
script that program is the script, so you see examples/shell_tour.sh or
starter/shell_tour.sh. To see your interactive shell, type echo $0 directly
in your terminal (not through the script) — it will print something like
-zsh or bash.
echo "$PS1" prints an empty line (or the tour says "empty")
PS1, the prompt-string template, is normally only set in interactive shells,
so a script usually sees it empty — the tour prints a note instead of a value.
Run echo "$PS1" in your interactive terminal to see the real template (for
example %n@%m %1~ %# in zsh). Keep the double quotes; without them the shell
may mangle the special characters.
history | tail shows nothing
history is a feature of interactive shells; a script often starts with an
empty history list, which is why the tour prints a placeholder note. Run
history | tail directly in your terminal after running a few commands and you
will see your logbook.
Permission denied when running the script
You don't need to make it executable — run it through bash explicitly:
bash starter/shell_tour.sh. If you prefer ./starter/shell_tour.sh, first run
chmod +x starter/shell_tour.sh.
Tests fail on a field that is still unknown
That check is telling you an exercise is unfinished — search the starter for
"unknown" and complete the remaining assignments, replacing each with the
command named in its comment, wrapped in $(...).
ps -p $$ looks different from the sample
Column formatting and the TTY value vary by OS and by how you launched the
shell; the important part is that a single process row for your current shell
appears. This is expected and not a failure.
Windows: bash is not recognized
Use WSL (wsl --install, then open Ubuntu and run the scripts unmodified), or
skip the script and type the individual commands from the lesson's hands-on
section in your terminal, filling the worksheet manually.
Security notes
Security notes — Day 008 lab
- What the scripts do: read information about your current shell session
(
echo $0,echo $SHELL,ps -p $$,echo "$PS1") and run a few read-only commands (pwd,echo,date,whoami,history,type). They make no network connections, write no files, and change no settings. - Privileges: everything runs as your normal user. Nothing in this lab needs
sudo; if any tutorial ever asks you tosudoa script you haven't read, that is your cue to stop and read it — a habit this course reinforces, because a shell runs whatever you type with your full privileges and asks no questions. - Privacy: a shell profile (username, working directory, shell version) is mildly identifying. Sharing it in a class forum is normally fine; avoid posting profiles of employer-managed machines. Remember that your shell records a history file on disk — so never type passwords or secret keys directly on a command line, where they would be logged in plain text.
- Reading before running: both scripts are short and commented — read them first. Running unread shell scripts from the internet is one of the most common ways developers get compromised; the course's rule is that every lab script is small enough to read and understand before executing.