# 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 November 10, 2026

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:

```bash
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](https://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:

```text
# 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:

```bash
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:

```text
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:

   ```bash
   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:

   ```bash
   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

- [Command History](https://www.ask-codey.com/glossary/command-history)
- [History Expansion](https://www.ask-codey.com/glossary/history-expansion)
- [Glob](https://www.ask-codey.com/glossary/glob)
- [Exit Code](https://www.ask-codey.com/glossary/exit-code)
- [Command Chaining](https://www.ask-codey.com/glossary/command-chaining)

## Related

- [Keyboard Shortcuts at the Prompt](https://www.ask-codey.com/lessons/bash-keyboard-shortcuts)
- [History Tricks: !!, !$ and Ctrl+R](https://www.ask-codey.com/lessons/bash-history-tricks)
- [Jumping Around: cd -, pushd and \*\*](https://www.ask-codey.com/lessons/bash-jumping-around)
- [Did It Work? Exit Codes, && and ||](https://www.ask-codey.com/lessons/bash-exit-codes)

Source: https://www.ask-codey.com/lessons/exercise-bash-fewer-keystrokes
