Exercise: Fewer Keystrokes

Write the settings that make your shell faster into a file of your own, count a photo project's photos four folders deep with **, read two exit codes, and write one line that backs up the beach photos and says so only if it worked, then let a check script tell you what's done.

Journeyman · Unix · Linux · Updated

A spring photo show is coming, and its photos sit four folders deep: originals by month and place, edited copies beside them, and an exports folder for the finished ones. You'll be in and out of those folders all week, so this is the moment to make the shell fast. Your job is to write the settings you learned in this chapter into a file of your own, use ** to count the photos, read two exit codes, and write a backup line that only reports success when there was one. A check script looks at your work and tells you which jobs are done.

Before you start

You need a terminal: the Terminal app on a Mac, or Ubuntu on Linux or in WSL on Windows. The check runs with bats, a small program that runs checks written for bash. If bats --version doesn't print a version number yet, install it:

sudo apt install bats       # Ubuntu, and Ubuntu in WSL
brew install bats-core      # a Mac, with Homebrew

sudo asks for your password, the one you use to sign in; nothing shows on the screen while you type it. On a Mac, the check loads your settings in bash 5, the bash you installed with Homebrew, even though your Terminal runs zsh.

Get the exercise code

Open this lesson's GitHub repository, github.com/ask-codey/exercise-bash-fewer-keystrokes, also linked from the Exercise box beside the lesson. Click Code, then Download ZIP, and unzip it into your terminal-practice folder as exercise-bash-fewer-keystrokes. Or clone it with Git.

The folder holds:

  • photo-show/: the project. raw/2026/ holds the original photos by month and place, edited/2026/ the edited copies (their names end in -edit.jpg), exports/ the finished ones, and notes.txt the plan. The photos are short text files with photo names.
  • fast.bashrc: six settings to write, one under each comment.
  • answers.txt: six questions, each with a numbered line for your answer.
  • check.bats: the check. You don't need to change it.

What to do

Open a terminal and cd into the exercise folder (the one with answers.txt in it). Then work through the jobs:

  1. Write the settings. Open fast.bashrc in nano (nano fast.bashrc) and write one line under each comment: a history of 10000 commands in memory and 20000 in the file, histappend, saving each command as it runs, globstar, and a CDPATH with . first and then photo-show's full path, not exported (History Tricks: !!, !$ and Ctrl+R, Jumping Around: cd -, pushd and **). Save, load it with source fast.bashrc, and try each one: echo $HISTSIZE, ls photo-show/raw/**/*.jpg, then cd ~ and cd edited. Your own ~/.bashrc stays as it is.
  2. Count and test. Answer questions 1 to 4 in answers.txt: two counts with ** and wc -l, and two exit codes with echo $? (Did It Work? Exit Codes, && and ||).
  3. Back up the beach photos. Question 5 asks for one line that makes a backup folder, copies the edited beach photos into it, and prints Backup done only if both of those worked. Write it in answers.txt, then run it in the exercise folder.
  4. Answer question 6, about history expansion.

The file starts like this:

# Example: how many folders are right inside photo-show? (ls photo-show)
# 0) 3

# 1. How many raw photos (.jpg files) are there in photo-show/raw, in all the folders below it?
1)

The check can't see your keystrokes, so practice them as you go: Alt+. to bring back a path, Ctrl+A and Ctrl+E to fix a line, Ctrl+R to find a command again, and pushd photo-show/raw/2026/05-may/beach and popd for a trip there and back (Keyboard Shortcuts at the Prompt).

Check your work

From the exercise folder:

bats check.bats

At first most checks fail. That's expected: each job you finish turns its check into a ✓. A failing check names the job and gives a hint, for example Question 5: with the beach folder gone, the copy failed, but your line still printed Backup done. Join the steps with && ("and then, if it worked"), not ;. To test your backup line, the check runs it twice in copies of the folder: once as it is, and once with the beach photos gone.

Hints

  • Settings are plain lines. NAME=value, with no spaces around the =. histappend and globstar are turned on with shopt -s, and PROMPT_COMMAND needs quotes around history -a because of its space.
  • Find photo-show's full path with cd photo-show and pwd. In fast.bashrc, $HOME can stand for the start of it.
  • Turn on globstar first. Until shopt -s globstar runs in your terminal (or you source fast.bashrc), ** works like *.
  • Only .jpg files count in question 1. One folder holds a screenshot and another a shot list.
  • echo $? comes straight after the command you're asking about; any command in between replaces the code.
  • &&, not ;. The backup line must stay quiet when the copy fails.

When you're done

Every check passes:

check.bats
 ✓ the photo-show folder is still here
 ✓ fast.bashrc loads without errors
 ✓ fast.bashrc: a longer history, 10000 commands in memory and 20000 in the file
 ✓ fast.bashrc: every terminal adds to the history file, as soon as each command runs
 ✓ fast.bashrc: ** reaches every folder below
 ✓ fast.bashrc: CDPATH looks here first, then in photo-show, and isn't exported
 ✓ 1) how many raw photos
 ✓ 2) how many edited photos
 ✓ 3) the exit code when grep finds nothing
 ✓ 4) the exit code when the file isn't there
 ✓ 5) the backup line copies the beach photos and says Backup done
 ✓ 5) the backup line stays quiet when the copy fails
 ✓ the backup folder holds the beach photos
 ✓ 6) going into the folder the last command made

14 tests, 0 failures

Your fast.bashrc is now a small file of settings you can carry. When you're ready to keep them, back up ~/.bashrc and copy the lines you want into it (Startup Files: .bashrc, .zshrc and source), with your own folders in CDPATH.

Submit your exercise

The exercise is how you finish this lesson. When your work is done, put it on GitHub in a repo of your own, then submit that repo's address here.

  1. On GitHub, click +, then New repository. Name it (for example exercise-bash-fewer-keystrokes), choose Public, and click Create repository. Leave out the README: your folder already has one.

  2. In a terminal in your exercise folder (Ubuntu in WSL on Windows), send your work to your new repo. If you downloaded the ZIP:

    git init -b main
    git add .
    git commit -m "My solution"
    git remote add origin https://github.com/your-name/exercise-bash-fewer-keystrokes.git
    git push -u origin main
    

    If you cloned the starter instead, point your copy at your own repo, then commit and push:

    git remote set-url origin https://github.com/your-name/exercise-bash-fewer-keystrokes.git
    git add .
    git commit -m "My solution"
    git push -u origin main
    
  3. Paste your repo's address, such as https://github.com/your-name/exercise-bash-fewer-keystrokes, into Submit your exercise on this page. The site checks that the repo is public and holds your commits, and then the lesson is complete.

Changed something after you submitted? Push it, and submit again: your latest submission is the one that counts.

So what

A shell that remembers a month of commands, reaches every folder with **, finds your project from anywhere and only reports success when there was one is how people who live in the terminal stay fast, and now yours is set up the same way.

Key terms

Related