Off track

There’s a pretty stupid error in the playing shell script I gave in a post two days ago, and it needs to be corrected.

The script is basically a wrapper around some AppleScript code that asks iTunes for the name, artist, and album of the currently-playing track. When I first wrote it, many moons ago, it was with the thought that I would invoke it while writing a blog post, inserting its output into some appropriate spot in the post. Upon reflection, this seemed a little too LiveJournal for a 40-something man, so I never used the script, even though it seemed to work perfectly. Of course, I never dreamed of invoking it unless iTunes was running.

Our story then picks up a couple of days ago, when I decided to give GeekTool a try. The old playing script seemed perfect for GeekTool, and it worked just fine—until I quite iTunes. A few seconds after iTunes quit, its icon would start bouncing in the Dock and it would relaunch. I’d quit it again and it would relaunch again, like a trick candle on a birthday cake that relights after you blow it out. Eventually, it got through my skull that GeekTool was calling playing every 10 seconds, and playing had that ‘tell application “iTunes”’ line that forced iTunes to launch if it wasn’t already running. I needed to check whether iTunes was running before that line.

For someone who spent some time in Linux/Unix-land, the natural thought is to use the ps command to find out if a process is active. But I first did a little Googling to see if there was a more Mac-specific way. One of the top hits was this macosxhints forum page, in which the original poster was clearly doing exactly what I was trying to do. And about a year-and-a-half ago, too. So I took one of his trial solutions, fixed it up a bit, and ended up with a two-part solution that seems to work while still allowing me to quit iTunes.

The first part is this AppleScript:

set notify to "Not playing"
tell application "iTunes"
  if player state is playing then
    set who to artist of current track as string
    set what to name of current track as string
    set onwhat to album of current track as string
    set notify to "\"" & what & "\" by " & who & " from " & onwhat
  end if
end tell
notify

which is very much like the set of AppleScript commands that were in the here document of my original shell script. This, though, is saved in a true AppleScript file, called itunes-playing.scpt and kept in my ~/bin/ directory.

The second part is this shell script:

#!/bin/bash
if [[ -n `ps x | grep "iTunes -psn" | grep -v grep` ]]; then
  osascript ~/bin/itunes-playing.scpt
else
  echo "iTunes off"
fi

which is what I now call playing. It checks whether iTunes is active before calling itunes-playing. The biggest difference between this and what’s given in the macosxhints forum page is the conditional line that calls ps. I found that grepping on “/Applications/iTunes.app” (as on the forum page) didn’t work because I have the iTunes Helper application running—because iTunes Helper runs out of /Applications/iTunes.app/, the grep would always come up positive. My solution was specific to iTunes itself.

By the way, piping the first grep through grep -v grep is a cute idea for eliminating the first grep from the output (the -v option reverses what grep normally does). It’s always bothered me that calling, say

ps x | grep hamburger

gives an output of something like

23362  p1  S+     0:00.01 grep hamburger

because I like to think that the command before the pipe is done before the command after the pipe is called. But clearly the two work sort of in parallel, otherwise the ps wouldn’t know that the grep is running.

Anyway, now that I have a more robust script, I can set up GeekTool like this

and I get the nice little notice at the bottom right of my screen.

Tags: