Advanced Bash-Scripting Guide. The section on Quoting explicitly warns Use double quotes to prevent word splitting. An argument enclosed in double quotes presents itself as a single word, even if it contains whitespace separators. Words to live by.

Apple pulls OS X version of iTunes 2. If you have multiple partitions, the iTunes 2.0.0 installer can wipe out everything on your secondary partition. Originally people thought it was simply a permissions problem, and that logging in as root and doing a chmod -R would solve the problem. But apparently there are two separate issues with the installer, the second of which can actually delete everything on your secondary partition. A post in the MacNN forums explains why:

Thanks to a tip in an email about the cause of the problem (spaces in volume names), I went digging into the package installer and think I found the source of the problem. The following code is in a file called ‘preflight’ inside the iTunes.pkg installer (in Contents/Resources):

# if iTunes application currently exists, delete it
if [ -e $2Applications/iTunes.app ] ; then
rm -rf $2Applications/iTunes.app 2< /dev/null
fi

So what’s the problem? If your volumes have spaces and are named similarly (let’s say “Disk”, “Disk 1″, and “Disk 2″), then this bug could bite you. The ‘$2′ variable that’s passed in contains the path to your selected iTunes installation destination. In our example, let’s assume it was headed for “Disk 1″. So ‘$2′ should contain /Volumes/Disk\ 1 (notice the backslash for the space). However, if it instead contained /Volumes/Disk 1, then the “rm -rf” command would execute TWICE. It would look like this:

rm -rf /Volumes/Disk 1/Applications/iTunes.app 2< /dev/null

One of the commands (the second half, ‘rm -rf 1/Applications/iTunes.app’) would probably not do anything, since the path is invalid. The second command, though, could be brutal. ‘rm -rf /Volumes/Disk’ would delete the entire volume ‘Disk’ used in this example.

Follow the community’s shock and disbelief on Slashdot, MacFixit, MacNN, and MacSlash.

Apple has acknowledged the problem and posted an updated version. Small consolation for those who have already lost data in this catastrophe. (I was unaffected, as I haven’t installed Mac OS X yet. The problem does not affect the Mac OS 9 version of iTunes, which, come to think of it, I’m not using either.)

Update A Slashdot post confirms that this is the cause of the problem, and shows Apple’s solution (from the newly-posted iTunes 2.0.1 installer):

The original installer script has the lines

# if iTunes application currently exists, delete it
if [ -e $2Applications/iTunes.app ] ; then
rm -rf $2Applications/iTunes.app 2> /dev/null
fi

while the replacement (2.0.1) has

# if iTunes application currently exists, delete it
if [ -e "$2Applications/iTunes.app" ] ; then
rm -rf "$2Applications/iTunes.app" 2> /dev/null
fi

In these scripts, $2 corresponds to the volume on which iTunes is to be installed, and will be of the form /Volumes/name-of-volume.

For those unfamiliar with Bourne shell variable expansion, if $2 has spaces in it, the argument to the rm command in the first version of the script will expand to more than one word, and rm will try and delete both of these. The -rf tells rm to delete everything down recursively and not complain about it.

This is particularly a problem on the Mac, where filenames and volume names often have spaces in them., even at the beginning of the name. If one had multiple partitions mounted in /Volumes, and the one on which iTunes was to be installed was called, say, ‘ OS X’, then the rm command would expand to

rm -rf /Volumes/ OS X/Applications/iTunes.app 2> /dev/null

and would then try and delete everything under /Volumes. This is clearly bad.

The second version, by including quotes around the argument, fixes the problem. The quotes force the argument to be treated as a single argument after variable expansion.

Traditionally, people have been super careful about destructive operations and shell expansions. I don’t think I’ve ever seen something like this written in a 3rd party script before, in fact (let alone from the OS vendor!). This could well be an example of programmers new to a Unix-like platform still getting used to the Unix way of doing things, and getting bitten as a result.

§

Respond privately

I am no longer accepting public comments on this post, but you can use this form to contact me privately. (Your message will not be published.)



§

firehosecodeplanet

© 2001–9 Mark Pilgrim