Just turned in the last chapter of Wicked Cool Shell Scripts!

Finally, after way too long writing this book about Unix / Mac OS X shell script programming, I’ve turned in the final chapter, a grand total of 101 most excellent scripts, all written for /bin/sh and portable to just about any Unix-like operating system on the planet. From the game of hangman to an Apache web log file analysis tool, from a cool iTunes music library listing utility to a powerful command-line calculator and currency conversion tool, there’s lots to check out! And, of course, it’s great to finally say and that’s a wrap!  

To whet your appetite, here’s the script for the game of hangman:

#!/bin/sh
# hangman - a rudimentary version of the hangman game. Instead of showing a
#   gradually embodied hanging man, this simply has a bad guess countdown.
#   You can optionally indicate steps from the gallows as the only arg.
wordlib="/usr/lib/games/long-words.txt"
randomquote="randomquote"
empty="\."      # we need something for the sed [set] when $guessed=""
games=0
if [ ! -r $wordlib ] ; then
echo "$0: Missing word library $wordlib" >&2
echo "(online at http://www.intuitive.com/wicked/examples/long-words.txt" >&2
echo "save the file as $wordlib and you're ready to play!)" >&2
exit 1
fi
while [ "$guess" != "quit" ] ; do
match="$($randomquote $wordlib)"      # pick a new word from the library
if [ $games -gt 0 ] ; then
echo ""
echo "*** New Game! ***"
fi
games="$(( $games + 1 ))"
guessed=""  ; guess="" ; bad=${1:-6}
partial="$(echo $match | sed "s/[^$empty${guessed}]/-/g")"
while [ "$guess" != "$match" -a "$guess" != "quit" ] ; do
echo ""
if [ ! -z "$guessed" ] ; then
echo -n "guessed: $guessed, "
fi
echo "steps from gallows: $bad, word so far: $partial"
echo -n "Guess a letter: "
read guess
echo ""
if [ "$guess" = "$match" ] ; then
echo "You got it!"
elif [ "$guess" = "quit" ] ; then
sleep 0           # this is a 'no op' to avoid an error message on 'quit'
elif [ $(echo $guess | wc -c | sed 's/[^[:digit:]]//g') -ne 2 ] ; then
echo "Uh oh: You can only guess a single letter at a time"
elif [ ! -z "$(echo $guess | sed 's/[[:lower:]]//g')" ] ; then
echo "Uh oh: Please only use lowercase letters for your guesses"
elif [ -z "$(echo $guess | sed "s/[$empty$guessed]//g")" ] ; then
echo "Uh oh: You have already tried $guess"
elif [ "$(echo $match | sed "s/$guess/-/g")" != "$match" ] ; then
guessed="$guessed$guess"
partial="$(echo $match | sed "s/[^$empty${guessed}]/-/g")"
if [ "$partial" = "$match" ] ; then
echo "** You've been pardoned!! Well done!  The word was \"$match\"."
guess="$match"
else
echo "* Great! The letter \"$guess\" appears in the word!"
fi
elif [ $bad -eq 1 ] ; then
echo "** Uh oh: you've run out of steps. You're on the platform.. and <SNAP!>"
echo "** The word you were trying to guess was \"$match\""
guess="$match"
else
echo "* Nope, \"$guess\" does not appear in the word."
guessed="$guessed$guess"
bad=$(( $bad - 1 ))
fi
done
done
exit 0

Yes, I know, you’ll need the ‘randomquote’ script for this to work. I’ll post that as a followup tonight, but this should be good reading in the meantime.

One comment on “Just turned in the last chapter of Wicked Cool Shell Scripts!

  1. Wooooow!!
    When I saw above script, I think is`s marvelous discovery!!
    It is a help to me, learning shell programing!!
    Specially pipe & string edit
    I deeply appreciate you 🙂
    ps. I am sorry I can`t english very well.

Leave a Reply

Your email address will not be published. Required fields are marked *