
I recently posted my "April" desktop on Filckr. Since then I've gotten a few requests for some of the GeekTool code. So here goes…
Let's start with the easy stuff.
Calendar

cal
Refresh: 300s, Font: Monaco
Pretty self-explanitory. It just brings up a calendar of the current month
Time
![]()
date '+%I:%M %p'
Refresh: 10s, Font: Helvetica Neue
The date command is pretty flexible. It's used often in my setup. The format string at the end is fairly basic, too. The '+' just signifies a user-defined format. %I is hours, %M minutes, and %p is the AM/PM designation. I really wanted to find a way to turn the AM/PM on 90°, but I don't think it's possible with GeekTool. The single quotes are necessary since there is a space in the format string.
Current Date

date +%d
Refresh: 300s, Font: Helvetica Neue
Again, date command. %d is the current day of the month.
Current Month
![]()
date +%B
Refresh: 300s, Font: Helvetica Neue
%B - current month, non-numeric
Day of the Week
![]()
date +%A
Refresh 300s, Font: Helvetica Neue
Self explanitory.
Now the fun parts:
Current Weather Conditions
![]()
curl --silent "http://xml.weather.yahoo.com/forecastrss?p=USWI0455&u=f" | grep -E '(Current Conditions:|F<BR)' | sed -e 's/Current Conditions://' -e 's/<br \/>//' -e 's/<b>//' -e 's/<\/b>//' -e 's/<BR \/>//' -e 's///' -e 's/<\/description>//'
Refresh: 1800s, Font: Helvetica Neue
That's a mouth full. Let's take this one piece by piece.
curl will take a url and dump the server response, most often the raw HTML. The '--silent' flag prevents curl from outputting a progress meter or error messages. The url of Yahoo's weather page follows in quotes. "CITYDATA" should be replaced with your results when you search for your city/zip on their site.
grep is a command line search utility. We're basically searching for the part of the XML file that starts with "Current conditions" and ends with "F
sed is basically taking out grep search results and paring it down to just the bit we want: the text of the current conditions.
IP Addresses:

myen0=`ifconfig en0 | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}'`
if [ "$myen0" != "" ]
then
echo "$myen0"
else
echo "INACTIVE"
fi
myen1=`ifconfig en1 | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}'`
if [ "$myen1" != "" ]
then
echo "$myen1"
else
echo "INACTIVE"
fi
wip=`curl --silent http://checkip.dyndns.org | awk '{print $6}' | cut -f 1 -d "<"`
echo "$wip"
Refresh: 60s, Font: Helvetica Neue
Yay full-on scripts! In simple words, this pulls the IP addresses from the ifconfig command for each interface (ethernet: en0, airport: en1). The fun bit comes in with the if-then statements. If no IP address is returned, it outputs "INACTIVE" instead of just a blank space. It just looks a little nicer. The last bit gets our external IP using curl on dyndns.org.
If you're wondering where the labels are in this code (Ethernet, Wireless, External). They're in a separate script with echo commands. It was just easier to get the spacing down that way.
Transmit Rate
![]()
mytr=`airport -I | awk '/lastTxRate/ {print $2}'`
if [ "$mytr" != "" ]
then
echo "Airport Transmit Rate: $mytr"
fi
Refresh: 5s, Font: Helvetica Neue
For some reason, my Leopard installation has trouble with keeping the transmit rate up. So I monitor it with this command. Now, by default, the airport command is not readily accessible. We make it that way with the following command in Terminal (found here):
sudo ln -s /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/sbin/airport
awk is another way of just pulling the info out we need, in this case "lastTxRate." the print $2 command limits the output to the second 'word,' in this case, the transmit rate in Mbps.
Uptime
![]()
uptime | awk '{sub(/[0-9]|user\,|users\,|load/, "", $6); sub(/mins,|min,/, "min", $6); sub(/user\,|users\,/, "", $5); sub(",", "min", $5); sub(":", "h ", $5); sub(/[0-9]/, "", $4); sub(/day,/, " day ", $4); sub(/days,/, " days ", $4); sub(/mins,|min,/, "min", $4); sub("hrs,", "h", $4); sub(":", "h ", $3); sub(",", "min", $3); print "Uptime: " $3$4$5$6}'
Refresh: 300s, Font: Helvetica Neue
Okay, this one is sloppy. I'm sure there is a better way to do this, but I just haven't found it. The code was cobbled together from this forum post and modified to work a little better. But I still get weird output for the first 60 minutes of uptime.
What does this do? uptime displays a few stats, but we're just interested in the hours, minutes, and days the computer has been up. Not number of users, etc. So this script just outputs and reformats that bit. All the sub commands substitute one bit of text for another. For example, instead of 'mins' I just wanted 'min', and instead of "3:42", I wanted it to say "3h 42min."
If anyone has any suggestions on how to clean this up or how to stop if from displaying the logged in users during the first 60 minutes (eg "15min1"), I'd love to hear it.
Now, my proudest moment:
Current Weather Image

Image URL - PHP script on my server
Refresh: 300s
The interesting bit isn't in GeekTool, but in the PHP script I wrote:
<?php
$url="http://weather.yahoo.com/forecast/CITYDATA.html"; //Yahoo Weather URL. Sub CITYDATA for your code.
$divStart = "<div class="\"forecast-icon\"";">$strEnd = "'); _background-image/* */: none;"; //HTML after weather image
$start = strpos($file_contents, $divStart) + 50;
$end = strpos($file_contents, $strEnd);
$length = $end-$start;
$imagepath=substr($file_contents, $start , $length); //Pulls path to image
$image=imagecreatefrompng($imagepath); //Pulls image source into PHP
imagealphablending($image, true); //Enable alpha blending (important)
imagesavealpha($image, true); //Applies alpha to image.
header('Content-Type: image/png'); //Identifies itself as a PNG image
imagepng($image); //Outputs image contents
?>
I tried to comment the code as best I can, but basically, it just pulls the raw HTML from Yahoo weather, extracts the image url for current conditions, and spits out that image data as if the script itself were that image. I might be violating some TOS, though, so your mileage may vary.
So that's my GeekTool setup. There's even more impressive things that people are doing like pulling Twitter feeds, so I suggest you hit up Google.
UPDATE (2009/04/16): Apparently some people have been having problems with these scripts. Due to the formatting in Wordpress, there may be some new line feeds or line wrapping that is preventing the scripts from working properly. And though I've been pretty thorough, there may be a place or two where it ate some HTML. In any case, I'm attaching a text file that has all the shell scripts and another text file with the PHP (which should be renamed with the .php extension before using)






