Overview of Bash Practice Exercises

4 minute read

Open a terminal and work through these exercises. They build on the concepts in this chapter.


Exercise 1 — Identify Your Shell Environment

Run the following commands and note the output. Then answer the questions below.

echo $SHELL
echo $0
bash --version
cat /etc/shells

Questions:

  1. What is your default login shell ($SHELL)?
  2. What shell is currently running ($0)?
  3. What is the major version of Bash installed?
  4. How many shells are available on your system?
Show Expected Output (Ubuntu 22.04)
$ echo $SHELL
/bin/bash

$ echo $0
bash

$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/usr/bin/sh
/bin/dash
/usr/bin/dash

Answers:

  1. /bin/bash — default login shell
  2. bash — the running shell
  3. 5 (major version from bash --version)
  4. 8 shells listed (varies by system)

Exercise 2 — Interactive Shell Detection

Create a script that detects whether it is running interactively and prints a message accordingly.

Requirements:

  • Script should print "Running interactively" or "Running non-interactively (script mode)"
  • Run it two ways: (a) as a script, (b) source it in your terminal
Show Answer
#!/usr/bin/env bash
# Save as: check-mode.sh
# chmod +x check-mode.sh

if [[ $- == *i* ]]; then
  echo "Running interactively"
else
  echo "Running non-interactively (script mode)"
fi
# Run as a script (non-interactive):
$ bash check-mode.sh
Running non-interactively (script mode)

# Source it in your terminal (interactive — sources into current shell):
$ source check-mode.sh
Running interactively

Exercise 3 — Terminal Keyboard Shortcuts Drill

Practice these shortcuts until they feel natural. Open a terminal and try each one:

  1. Type a long command (e.g., echo "hello this is a long command") but do not press Enter. Use Ctrl+A to jump to the beginning, then Ctrl+E to jump to the end.

  2. Type ping google.com and press Enter. After 3-4 lines of output, press Ctrl+C to stop it. Note the “statistics” line that appears.

  3. Start ping google.com again, press Ctrl+Z to suspend it. Then type fg to bring it back to the foreground, and Ctrl+C to kill it.

  4. Use Ctrl+R and type ping to find the ping command in your history.

Show Expected Output
# Exercise 3.2 — Ctrl+C stops ping
$ ping google.com
PING google.com (142.250.80.46): 56 data bytes
64 bytes from 142.250.80.46: icmp_seq=0 ttl=115 time=12.3 ms
64 bytes from 142.250.80.46: icmp_seq=1 ttl=115 time=11.8 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss

# Exercise 3.3 — Ctrl+Z suspends, fg resumes
$ ping google.com
PING google.com (142.250.80.46): 56 data bytes
^Z
[1]+  Stopped                 ping google.com
$ fg
ping google.com
64 bytes from 142.250.80.46: icmp_seq=3 ttl=115 time=12.1 ms
^C

Exercise 4 — Bash Version Check Script

Write a script that:

  1. Prints the current Bash version
  2. Warns if the version is below 4
  3. Confirms if the version is 4 or higher
Show Answer
#!/usr/bin/env bash
# Save as: check-bash-version.sh

echo "Bash version: ${BASH_VERSION}"
echo "Major version: ${BASH_VERSINFO[0]}"

if [[ ${BASH_VERSINFO[0]} -lt 4 ]]; then
  echo "⚠️  WARNING: Bash 4+ recommended. Associative arrays and mapfile not available."
  echo "   On macOS, install: brew install bash"
else
  echo "✅ Bash ${BASH_VERSINFO[0]} — all modern features available."
fi
# Expected output on Ubuntu 22.04:
$ bash check-bash-version.sh
Bash version: 5.1.16(1)-release
Major version: 5
✅ Bash 5 — all modern features available.

# Expected output on macOS (default Bash):
Bash version: 3.2.57(1)-release
Major version: 3
⚠️  WARNING: Bash 4+ recommended. Associative arrays and mapfile not available.
   On macOS, install: brew install bash

Exercise 5 — .bashrc vs .bash_profile

Question: Explain what happens in each scenario:

  1. You add alias ll='ls -la' to ~/.bashrc. You open a new terminal. Does ll work?
  2. You add export MY_VAR="hello" to ~/.bash_profile. You SSH into your server. Does echo $MY_VAR show “hello”?
  3. You run bash myscript.sh. The script contains ll. Does it work?
  4. You source ~/.bashrc from your terminal. You then run bash myscript.sh. Does ll work in the script now?
Show Answer
  1. ✅ Yes — A new terminal window opens a non-login interactive shell which reads ~/.bashrc. The ll alias is available.

  2. ✅ Yes — SSH opens a login shell which reads ~/.bash_profile. MY_VAR is set and exported, so echo $MY_VAR shows “hello”.

  3. ❌ No — bash myscript.sh runs in a non-interactive shell. ~/.bashrc is not loaded. Aliases are not available. Use ls -la instead.

  4. ❌ Still No — Even though you sourced ~/.bashrc in your terminal session, the alias ll is only available in your current interactive shell. When you run bash myscript.sh, it launches a new, separate non-interactive shell with no aliases. Aliases are never inherited by child processes.


Chapter 2 Complete ✅

You now understand:

  • What a shell is and how it interprets commands
  • The difference between Bash, sh, zsh, and fish
  • Why macOS ships old Bash 3.2 and how to install Bash 5
  • Terminal emulators and essential keyboard shortcuts
  • Interactive vs non-interactive mode — and why aliases don’t work in scripts
  • The shebang line and why #!/usr/bin/env bash is the best practice

Next Chapter → Why Linux Matters

Updated: