How to Make Your Mac Automatically Load Up Your Kindle

Writing about technical writing is fun and all, but it’s fun to write a tutorial every now and then too. Here’s a look at something I’ve been working on recently.

I love reading on my Kindle. For stuff longer than your average blog post, the Kindle is vastly preferable to even the finest back-lit display. So in addition to the books I buy from Amazon, I load up my Kindle with stuff from a variety of sources. For example: I recently found out about NASA’s free ebook collection and immediately picked out some promising titles or I take advantage of my local libraries’ OverDrive subscriptions to check out books.

After a day or two, I’ll often end up with a bunch of articles and books to dump on my Kindle. Now, I could pay Amazon to wirelessly deliver to my device1, but I’d have to leave the wireless turned on, considerably reducing battery life. I figure I may as well save money and battery by loading the files over USB, since I’ll be plugging in to charge on occasion anyway. So I have a process:

  1. Put new ebook files in a folder called Reading Material.
  2. Connect Kindle to the computer.
  3. Copy the contents of Reading Material to the Kindle’s documents directory.
  4. Eject the Kindle. See the files appear on the Kindle’s home screen listing of available documents.

That’s easy enough, I guess, but I thought I could do better. My preferred scenario would be that I plug the Kindle in and the computer does the rest. After a bit of tinkering, it turns out this scenario is pretty easy to pull off. All it takes is a Bash script, a launchd plist file, and a couple of commands at the terminal. So here’s what to do:

First, we need a script that’s going to run each time a new drive is connected to move files to the Kindle. The script will run any time a new drive is mounted (not just the Kindle), so we’ll need to check the right storage device is available before doing anything. And there are other boring details to deal with. I’ve taken the liberty of writing, though you’ll need to to tweak it to your specific situation. Please see README.rst for all the gory installation and configuration details.

Next, we need to tell OS X to run the script whenever a new volume is mounted. Mac OS X features a service called launchd which can be used to schedule scripts to run at certain times (much like cron, if you’re already familiar with that) or under certain conditions.

In our case, we want to run whenever a new volume appears. We can do that pretty easily by adding a file to the ~/Library/LaunchAgents directory. launchd is controlled by plist (as in property list) files which are XML files using a special Apple XML DTD. It’s kind of ugly and a pain to work with, but this use case is fairly understandable:

Save the file as ~/Library/LaunchAgents/com.[username].KindleLoader.plist, where [username] is your Mac OS X username. Then open up the Terminal application and enter launchctl load $HOME/Library/LaunchAgents/com.[username].KindleLoader.plist and press Enter to register it with launchd.

Alternatively, you can use a tool which will create, edit, and register the file for you. One is Lingon (as in lingonberry, yummy), available on the Mac App Store. I haven’t used Lingon since a long time ago when it was free and the MAS was just a glare in Steve Jobs’s eye, but it’s an option if you don’t want to mess with plsit files yourself.

Now, when you plug your Kindle into your Mac, your new reading material will be automatically loaded and the dulcet tones of Alex’s voice will announce the proceedings (or you can turn that off, if you read the README like I suggested). Then the Kindle will be automatically ejected for immediate use (don’t worry, it’ll keep charging as long as the cable is connected).

And that’s how you can reduce the friction between you and reading, at least a little bit.

Note 1: Kindles with WiFi can avoid the fee by skipping the 3G network. My Kindle 2 doesn’t have WiFi and I don’t feel the need to upgrade and give up my nice, wide page turning buttons.  ↩