Dropbox Now Syncs Extended Attributes

Extended Attribute Sync – Syncing resource forks have historically been a pain for Mac users. In case you don’t know, resource forks are a secret area of a file that certain applications like Quicken, Quark, and OmniGraffle use to store important data. Most sync programs today completely ignore these forks, which results in a corrupted file on the other end. But worry not! Resource forks and other extended attributes now work great with Dropbox. Hooray!

via The Dropbox Blog » Blog Archive » Dropbox hits 1.0!.

This is great news. I use Dropbox to sync my ~/Library/Scripts and ~/Library/Services folder across multiple computers.1

While AppleScript files usually work, some Automator Workflow files store extra information in extended attributes and those would break when syncing. Now with the latest version of Dropbox things work fine.

If you don’t use Dropbox yet, you should try it. You can support scriptingosx.com a little by signing up to Dropbox through this link, then both you and me will get some extra free storage space.


  1. the way I do that is to move all scripts and/or workflows I want to sync to ~/Dropbox/Scripts or ~/Dropbox/Services and replace the actual folder in ~/Library with a symlink: ln -s ~/Dropbox/Scripts ~/Library/Scripts

Shell Loop Interaction with SSH

If you have a bash script with a while loop that reads from stdin and uses ssh inside that loop, the ssh command will drain all remaining data from stdin1. This means that only the first line of data will be processed.

I encountered this issue yesterday2. This website explains why the behavior occurs and how to avoid it.

A flawed method to run commands on multiple systems entails a shell while loop over hostnames, and a Secure Shell SSH connection to each system. However, the default standard input handling of ssh drains the remaining hosts from the while loop

from Shell Loop Interaction with SSH.


  1. This is not only true for ssh but for any command in the loop that reads from stdin by default
  2. I won’t go into details here, since it is for a very specialized purpose. I will say that it involved jot, ssh, an aging Solaris based network appliance, and some new fangly XML/Web 2.0

Automatically connect to Airfoil Speakers

Update: In one of those embarrassing “You know there is a checkbox for that!?” moments, @rogueamoeba points out there is in fact a checkbox for this under Preferences “Automatically Transmit To:”


Airfoil from Rogue Amoeba is a wonderful application that allows you to stream audio from your computer to any device that will receive Airplay audio or run the Airfoil Speaker application. This includes all iOS devices. I use it stream audio to any room I may be in where I just hook an iPod touch or the iPhone up to the stereo.

The one drawback is the UI, which only allows to the devices to stream to on the Mac that is streaming. So I’ll be in the kitchen, where a 1G iPod touch is permanently hooked up to some speakers, turn on the iPod touch, start the Airfoil speakers app, then walk to the Mac in the living room, select the iPod touch in the Kitchen and walk back to enjoy the music. Wouldn’t it be great if Airfoil automatically picked up the iPod when it appears in the list?

Luckily Airfoil has AppleScript support. It is actually very easy. I have named all my iOS device to start with either “iPhone”, “iPad” or “iPod touch” so I can make Airfoil connect to all devices that are running the Airfoil app with

tell application "Airfoil"
    connect to every speaker whose name starts with "iP"
end

Now we need to keep running this command periodically in the background. I could setup a launchd plist for that, but AppleScript provides a simpler solution. Scripts that are saved as “Stay Open Applications” have an idle handler that is called after a certain number of seconds. See the details at the AppleScript Language Guide here.

So we wrap the command in an idle handler and add some checking to see if Airfoil is running so we don’t force launch Airfoil:

property idleTime : 30 -- in seconds

on run
	idle -- call idle on launch
end run

on idle
	tell application "System Events"
		if exists application process "Airfoil" then -- check if Airfoil is running
			tell application "Airfoil"
				connect to (every speaker whose name starts with "iP" and connected is false)
			end tell
		else -- if Airfoil is not running script can quit, too
			tell me to quit
		end if
	end tell
	
	return idleTime
end idle

The value returned from the idle handler is the time (in seconds) until it gets called again. This will leave other speakers (that don’t start with “iP”) such as the local speakers and any Airport Express speakers unaffected.

Save this as an application and make sure to select the “Stay Open” option. Then find the application and double click to launch. Start and quit Airfoil speakers app on your iOS devices and listen to Airfoil connect automatically.

Some ssh Tricks

I found this website with a bunch of ssh tricks. Some highlights:

Compare a Remote File with a Local File

ssh user@host cat /path/to/remotefile | diff /path/to/localfile -

Useful for checking if there are differences between local and remote files.

opendiff1 and bbdiff2 do not use stdin for their input, but you can work around that by copying the file to /tmp first:

scp user@host:/path/to/remotefile /tmp/remotefile && opendiff /path/to/localfile /tmp/remotefile

SSH Connection through host in the middle

ssh -t reachable_host ssh unreachable_host

Unreachable_host is unavailable from local network, but it’s available from reachable_host’s network. This command creates a connection to unreachable_host through “hidden” connection to reachable_host.

Using the -t option uses less overhead on the intermediate host. Same trick is used later in the article where you directly attach to a remote screen session:

ssh -t remote_host screen -r

Though I prefer using screen -DR. Read the man page for details.

The next one however didn’t do anything for me, I suspect there is a piece missing in the command somewhere:

Remove a line in a text File

sed -i 8d ~/.ssh/known_hosts

However there is a dedicated tool for this: use

ssh-keygen -R host

instead. I re-image some machines over and over again and then run into the ssh host key errors. This is very useful.


  1. Part of the Developer Tools installed with Xcode
  2. One of the tools installed by BBEdit

Enable Some Extra Services

It’s Thanksgiving here in the US. To keep you happy with minimal effort on my side I’ll give you a whole bunch of services to explore, without me (or you) having to write any of them.

Open System Preferences, select the Keyboard preference pane, select the Keyboard Shortcuts Pane and then from the list on the left select “Services.”

There you will find a long list of pre-installed services many of which are disabled by default. Go through the list and enable those that sound promising. “Get Result of AppleScript” and “Add to iTunes as Spoken Track” are two of my favorites.

Any services you have built yourself will also appear in this list. You can disable or re-enable them to keep your context menu trim.

This pane is also where you assign or change keyboard shortcuts. So if there is a service that you use frequently you can further optimize your workflow with a keystroke.