Exercise: Rename the Telemetry

Write two small tools for Mission Control, a script that renames every .tmp file in a folder and one that pulls the warnings out of a flight log, then run them on the real files and let a check script tell you what's done.

Apprentice · Unix · Linux · Updated

It's launch day at Mission Control, and the ground station needs two small tools. The satellite's 21 telemetry files came in ending in .tmp instead of .log, and the flight director wants every warning from last night's flight log in one short report. You'll write both as scripts, small applications that work on whatever folder or file they're given, then run them on the real files. A check script tries each one on files of its own and tells you what's 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.

Get the exercise code

Open this lesson's GitHub repository, github.com/ask-codey/exercise-bash-rename-the-telemetry, also linked from the Exercise box beside the lesson. Click Code, then Download ZIP, and unzip it into your terminal-practice folder. Or clone it with Git. On Windows, put it inside Ubuntu, in your Linux home folder, not in a Windows folder under /mnt/c, so chmod works on the scripts.

The folder holds:

  • rename.sh and warnings.sh: the two scripts. Each starts with a comment that says exactly what it must do. These are the files you write.
  • telemetry/: the 21 telemetry files, all ending in .tmp. One has spaces in its name.
  • flight-log.txt: last night's flight log, with notes from the night shift and a few lines after the end.
  • check.bats: the check. You don't need to change it.

What to do

Open a terminal in the exercise folder, make the scripts runnable (Your First Script), and open the first one in nano:

chmod +x rename.sh warnings.sh
nano rename.sh
  1. rename.sh FOLDER renames every .tmp file in the folder it's given to end in .log, prints a line for each file it renames, and ends with Files renamed: 21 (or however many it renamed). Run a second time, with nothing left to rename, it prints Files renamed: 0 and no error.

  2. warnings.sh LOGFILE reads the log one line at a time, skips the notes that start with #, stops at the line END OF FLIGHT, prints every other line with WARNING in it exactly as written, and ends with Warnings found: 3 (or however many it printed).

  3. Use them. Try rename.sh on a copy first (cp -r telemetry practice, then ./rename.sh practice, then rm -r practice). When the checks for a script pass, run it on the real files:

    ./rename.sh telemetry
    ./warnings.sh flight-log.txt > warnings.txt
    

rename.sh uses a for loop and warnings.sh uses while IFS= read -r line, and each works on its $1 (Arguments: $1, $# and "$@"), never on a name written into the script.

Check your work

From the exercise folder:

bats check.bats

At first almost every check fails. That's expected: each job you finish turns its checks into a ✓. The check tries your scripts on made-up files of its own, in a throwaway folder, and only the last two checks look at your telemetry/ folder and warnings.txt. A failing check says what to look at, for example With four .tmp files, the last line should be: Files renamed: 4. Start a counter at 0 before the loop, add 1 for each file inside it, and print it after done.

Hints

  • The renaming line is the one from For Every File: for Loops. In for f in "$1"/*.tmp, the double quotes go around $1 only, so the * still matches.
  • Look before you rename: put echo in front of mv and run the script on your practice copy.
  • The count starts at 0 before the loop and grows inside it (Stopping Early: break, continue and Counters), and the same lesson shows the line that makes a loop safe to run twice.
  • Spaces and backslashes in the log must come out as they went in: Line by Line: while read says which part of the loop keeps each, and echo "$line" needs its double quotes.
  • Inside [[ ]], $line == "#"* means "starts with #", and $line == *WARNING* means "has WARNING somewhere in it".

When you're done

Every check passes:

check.bats
 ✓ rename.sh and warnings.sh are here
 ✓ 1) rename.sh renames every .tmp file in the folder it's given
 ✓ 2) rename.sh prints how many files it renamed
 ✓ 3) rename.sh is safe to run twice
 ✓ 4) rename.sh uses a for loop
 ✓ 5) warnings.sh prints each warning exactly as written
 ✓ 6) warnings.sh skips the notes that start with #
 ✓ 7) warnings.sh stops at END OF FLIGHT
 ✓ 8) warnings.sh prints how many warnings it found
 ✓ 9) warnings.sh reads the log with while IFS= read -r
 ✓ 10) the telemetry folder is renamed
 ✓ 11) warnings.txt holds the flight log's warnings
12 tests, 0 failures

Now look back at rename.sh. It renames .tmp to .log and nothing else. What would you change so the same script could turn .JPG into .jpg in your photos folder, without writing a new one?

Want the whole mission? Play Mission Control from the start in Terminal Quest: play it on the game's page. It has the telemetry and the sensor check from this chapter, a beacon that takes an argument, and the launch itself. One goal stops a runaway program with ps and kill, which are new here; the Step by step hints show you how. The game keeps your place in this browser, so you can stop and come back.

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-rename-the-telemetry), 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-rename-the-telemetry.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-rename-the-telemetry.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-rename-the-telemetry, 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

You wrote two tools that do in a second what would take an hour by hand, on 21 files or 2,000, and are safe to run again tomorrow: that is what a script that's an application looks like.

Key terms

Related