Technology: the only way to be a wizard if Hogwarts won't have you.

The Fortunes of Linux

Date/Time Permalink: 04/21/06 05:44:15 pm
Category: HOWTOs and Guides

One of the things that grabbed me right away about Linux, bibliophile that I am, was that a Linux system is never short of things to read. From the expansive documentation to the cheekily humorous stuff in /emacs../etc to the source code itself, I always had plenty of text to keep my eyeballs busy during idle moments.

The fortune system has charmed me, perhaps a little more than it's authors intended. the program is /usr/games/fortune and the archives of quotes are in /usr/share/games/fortunes/ . Whenever I try a new Linux distro, if it has fortune files that I don't have, I copy it to my home collection. If I find a version that's longer, I merge in the changes.

Recently, I got a little tired of the fortune binary itself, however. It happens that (a) I am offensive-proof, and (b) really don't care if one file hits three times more often than another file. The fortune program itself strikes me as a bit silly. I just want *any* random quote from *any* random file. The fortune manpage takes you through this intricate dance of options and then you have to be sure the file you add is in the list, and worst of all, it won't work period without a compiled binary something next to it called a ".dat" file. Which means that if you find a typo or a duplicated fortune and want to fix it, this is an actual *compile* we're talking about.

Well, if you users want to live that way, this is a good way to do it over on Brad's technical pages. My way:

ls /usr/share/games/fortunes/ | grep -v 'dat' > /tmp/fortfiles.temp
sedfeed=$(($RANDOM%$(wc -l /tmp/fortfiles.temp | awk '{print $1}')+1))"p"
fortfile="/usr/share/games/fortunes/"$(sed -n $sedfeed /tmp/fortfiles.temp)
grep -n "%$" $fortfile > /tmp/fortfiles.temp
linepick=$(($RANDOM%$(wc -l /tmp/fortfiles.temp | awk '{print $1}')+1))
fortunestart=$(sed -n $sedfeed /tmp/fortfiles.temp | sed 's/:%//')
fortunestop=$(sed -n $sedfeed /tmp/fortfiles.temp | sed 's/:%//')
sed -n $sedfeed $fortfile | sed 's/%//g'

rm /tmp/fortfiles.temp

exit 0

Consider the advantages: On today's modern machines, you will not notice the microsecond's lag between the binary hash and this script. It's simpler - you'll always know what it does. It doesn't need ".dat" files. Edit what you want when you want - your changes will reflect instantly, without having to make another step. Add more with impunity - here's an archive of them. With South Park and Powerpuff Girls! Yes, it's time we blew the dust off this stuffy old program and brought it into the 21st century. Here's a link to another site that links to fortune files.

After implementing this and deciding it was to my satisfaction, I edited my fortune files. I added %'s to the top of each file to ensure the first one had a chance to be picked, ensured that %'s were at the bottom of each file (not all of them do) rot13-decoded all my -o ('offensive') files and resolved to unflinchingly view the most offensive things herewith, and took a deep breath and deleted the ".dat"s and the filelist. It's running well enough! In fact, it seems to be finally showing quotes from *all* files - I think I munged things up with the old program by snarfing files from too many different distros, and hence different versions of fortune, BSD fortune, and fortune-mod.

All in all, I think I made a good trade-off. I realize that a binary reading hashes was necessary back in 1995, but these days a shell script can do the job just as fast. I'm ready to nominate that we just ditch the 20 different versions of the fortune program and keep to a standard for fortune files like with RSS, and parse with shell scripts like these. Here's the standard for fortune files:

Seperate quotes with percent signs.

There, let's call it RFC-$NUMBER. Shouldn't be too hard, eh?

Follow me on Twitter for an update every time this blog gets a post.
Stumble it Reddit this share on Facebook

suddenly the moon