The Adventures of Systems Boy!

Confessions of a Mac SysAdmin...

Scripts Part 7: Contextual Menus with Automator

Saturday, March 31, 2007
Recently, for some odd reason, there has been a spate of solutions to the problem of creating new files in the Finder via a contextual menu. One involves a contextual menu plugin called NuFile. Another involves installing Big Cats Scripts and linking it to an Applescript. But honestly — and I'm surprised someone else didn't think of this first — when faced with simple contextual menu tasks, these days my first thought is to look to Automator.

And by golly, that's just what I did. Here are a few Automator workflows that do, more or less what the afore-linked methods do. To me, the advantage of the Automator approach is that you don't need to install anything. It's all baked in. Which means you don't ever need to update anything either. Nice. Simple. And, yeah, kind of the whole point of Automator.

So here you go. Maybe someone will find this useful, if for nothing other than as an exercise in creating contextual menu functionality with Automator. Or skinning a cat multiple ways. Or something. To use this, download the .zip file, unzip it and place it in:
~/Library/Workflows/Applications/Finder

NewTextFile Workflow

It should become active immediately.

Also, here are a couple variants. One will create a text file, and then open it in TextWrangler (if you have TextWrangler, and if you don't, go get it now); the other creates a Word document, and opens it in Word. I'm far to lazy to completely duplicate the functionality of NuFile. But if you examine these workflows, you can at least see now how that would be possible (in fact, fairly easy) to accomplish.

NewTextFile Workflow Variants

I actually think it would be great if Apple made it drop dead simple to create true contextual menus for the Finder. Fortunately, Automator gets us pretty close.

Oh, yeah, and since this is technically script writing, and since I haven't posted to that series in some time, we're gonna go ahead and call this a Script Sharing post. Deal with it.

Right. Good night.

UPDATE: Revised March 31, 2007, 3:00 PM
Stephan Cleaves has added yet another implementation of this idea. He's using a combination of Automator and AppleScript. I certainly think his implementation is better than mine in a few ways. Certainly more full-featured. It will prompt for a file name, for instance, and takes pains not to overwrite a preexisting file with the same name. Nice. But we're taking very different approaches to the same idea (his version places a file in the front-most Finder window, my version places it in the right-clicked folder), and he was confused by my approach. After speaking to him via comments on his blog, I realized that some clarification as to how my workflow is actually constructed might be in order.

Basically, my workflow takes the folder selected in the Finder as input and assigns that input to the variable "$@". That variable and the for loop in my workflow are automatically generated by Automator when you select “as arguments” from the “Pass input:” field in the “Do Shell Script” action. It’s how you get the context (the selected folder) passed to the script. Apparently Automator takes “$@” as the variable for “the folder you just selected” whenever there’s no input from a previous action. This was something I learned while fiddling around with all of this, and it's really my favorite part. The coolest thing for me here, really, was figuring out how to pass the context — i.e. the right-clicked folder — to an Automator "Do Shell Script" action. This opens up worlds of potential.

Finally, as I said, the for loop in the action is auto-generated by Automator. The workflow will work almost as well with the simple script:
touch “$@/NewText.txt”

Using the for loop, however, allows you to create a new text file in multiple folders by selecting said folders and running the workflow.

It's really kind of amazing how many ways there are to do this. Wow. Fun stuff.

Labels: , , , ,

Backing Up with RsyncX

Sunday, December 03, 2006
In an earlier post I talked generally about my backup procedure for large amounts of data. In the post I discussed using RsyncX to back up staff Work drives over a network, as well as my own personal Work drive data, to a spare hard drive. Today I'd like to get a bit more specific.

Installing RsyncX
I do not use, nor do I recommend the version of rsync that ships with Mac OS X 10.4. I've found it, in my own personal tests, to be extremely unreliable, and unreliability is the last thing you want in a backup program. Instead I use — and have been using without issue for years now — RsyncX. RsyncX is a GUI wrapper for a custom-built version of the rsync command that's made to properly deal with HFS+ resource forks. So the first thing you need to do is get RsyncX, which you can do here. To install RsyncX, simply run the installer. This will place the resource-fork-aware version of rsync in /usr/local/bin/. If all you want to do is run rsync from the RsyncX GUI, then you're done, but if you want to run it non-interactively from the command-line — which ultimately we do — you should put the newly installed rsync command in the standard location, which is /usr/bin/.¹ Before you do this, it's always a good idea to make a backup of the OS X version. So:

sudo cp /usr/bin/rsync /usr/bin/rsync-ORIG
sudo cp /usr/local/bin/rsync /usr/bin/rsync

Ah! Much better! Okay. We're ready to roll with local backups.²

Local Backups
Creating local backups with rsync is pretty straightforward. The RsyncX version of the command acts almost exactly like the standard *NIX version, except that it has an option to preserve HFS+ resource forks. This option must be provided if you're interested in preserving said resource forks. Let's take a look at a simple rsync command:

/usr/bin/rsync -a -vv /Volumes/Work/ /Volumes/Backup --eahfs

This command will backup the contents of the Work volume to another volume called Backup. The -a flag stands for "archive" and will simply backup everything that's changed while leaving files that may have been deleted from the source. It's usually what you want. The -vv flag specifies "verbosity" and will print what rsync is doing to standard output. The level of verbosity is variable, so "-v" will give you only basic information, "-vvvv" will give you everything it can. I like "-vv." That's just the right amount of info for me. The next two entries are the source and target directories, Work and Backup. The --eahfs flag is used to tell rsync that you want to preserve resource forks. It only exists in the RsyncX version. Finally, pay close attention to the trailing slash in your source and target paths. The source path contains a trailing slash — meaning we want the command to act on the drive's contents, not the drive itself — whereas the target path contains no trailing slash. Without the trailing slash on the source, a folder called "Work" will be created inside the WorkBackup drive. This trailing slash behavior is standard in *NIX, but it's important to be aware of when writing rsync commands.

That's pretty much it for simple local backups. There are numerous other options to choose from, and you can find out about them by reading the rsync man page.

Network Backups
One of the great things about rsync is its ability to perform operations over a network. This is a big reason I use it at work to back up staff machines. The rsync command can perform network backups over a variety of protocols, most notably SSH. It also can reduce the network traffic these backups require by only copying the changes to files, rather than whole changed files, as well as using compression for network data transfers.

The version of rsync used by the host machine and the client machine must match exactly. So before we proceed, copy rsync to its default location on your client machine. You may want to back up the Mac OS X version on your client as well. If you have root on both machines you can do this remotely on the command line:

ssh -t root@mac01.systemsboy.com 'cp /usr/bin/rsync /usr/bin/rsync-ORIG'
scp /usr/bin/rsync root@mac01.systemsboy.com:/usr/bin/

Backing up over the network isn't too much different or harder than backing up locally. There are just a few more flags you need to supply. But the basic idea is the same. Here's an example:

/usr/bin/rsync -az -vv -e SSH mac01.systemsboy.com:/Volumes/Work/ /Volumes/Backups/mac01 --eahfs

This is pretty similar to our local command. The -a flag is still there, and we've added the -z flag as well, which specifies to use compression for the data (to ease network traffic). We now also have an -e flag which tells rsync that we're running over a network, and an SSH option that specifies the protocol to use for this network connection. Next we have the source, as usual, but this time our source is a computer on our network, which we specify just like we would with any SSH connection — hostname:/Path/To/Volume. Finally, we have the --eahfs flag for preserving resource forks. The easiest thing to do here is to run this as root (either directly or with sudo), which will allow you to sync data owned by users other than yourself.

Unattended Network Backups
Running backups over the network can also be completely automated and can run transparently in the background even on systems where no user is logged in to the Mac OS X GUI. Doing this over SSH, of course, requires an SSH connection that does not interactively prompt for a password. This can be accomplished by establishing authorized key pairs between host and client. The best resource I've found for learning how to do this is Mike Bombich's page on the subject. He does a better job explaining it than I ever could, so I'll just direct you there for setting up SSH authentication keys. Incidentally, that article is written with rsync in mind, so there are lots of good rsync resources there as well. Go read it now, if you haven't already. Then come back here and I'll tell you what I do.

I'd like to note, at this point, that enabling SSH authentication keys, root accounts and unattended SSH access is a minor security risk. Bombich discusses this on his page to some extent, and I want to reiterate it here. Suffice to say, I would only use this procedure on a trusted, firewalled (or at least NATed) network. Please bear this in mind if you proceed with the following steps. If you're uncomfortable with any of this, or don't fully understand the implications, skip it and stick with local backups, or just run rsync over the network by hand and provide passwords as needed. But this is what I do on our network. It works, and it's not terribly insecure.

Okay, once you have authentication keys set up, you should be able to log into your client machine from your server, as root, without being prompted for a password. If you can't, reread the Bombich article and try again until you get it working. Otherwise, unattended backups will fail. Got it? Great!

I enable the root account on both the host and client systems, which can be done with the NetInfo Manger application in /Applications/Utilities/. I do this because I'm backing up data that is not owned by my admin account, and using root gives me the unfettered access I need. Depending on your situation, this may or may not be necessary. For the following steps, though, it will simplify things immensely if you are root:

su - root

Now, as root, we can run our rsync command, minus the verbosity, since we'll be doing this unattended, and if the keys are set up properly, we should never be prompted for a password:

/usr/bin/rsync -az -e SSH mac01.systemsboy.com:/Volumes/Work/ /Volumes/Backups/mac01 --eahfs

This command can be run either directly from cron on a periodic basis, or it can be placed in a cron-run script. For instance, I have a script that pipes verbose output to a log of all rsync activity for each staff machine I back up. This is handy to check for errors and whatnot, every so often, or if there's ever a problem. Also, my rsync commands are getting a bit unwieldy (as they tend to do) for direct inclusion in a crontab, so having the scripts keeps my crontab clean and readable. Here's a variant, for instance, that directs the output of rsync to a text file, and that uses an exclude flag to prevent certain folders from being backed up:

/usr/bin/rsync -az -vv -e SSH --exclude "Archive" mac01.systemsboy.com:/Volumes/Work/ /Volumes/Backups/mac01 --eahfs > ~/Log/mac01-backup-log.txt

This exclusion flag will prevent backup of anything called "Archive" on the top level of mac01's Work drive. Exclusion in rsync is relative to the source directory being synced. For instance, if I wanted to exclude a folder called "Do Not Backup" inside the "Archive" folder on mac01's Work drive, my rsync command would look like this:


/usr/bin/rsync -az -vv -e SSH --exclude "Archive/Do Not Backup" mac01.systemsboy.com:/Volumes/Work/ /Volumes/Backups/mac01 --eahfs > ~/Log/mac01-backup-log.txt

Mirroring
The above uses of rsync, as I mentioned before, will not delete files from the target that have been deleted from the source. They will only propagate changes that have occurred on the existing files, but will leave deleted files alone. They are semi-non-destuctive in this way, and this is often useful and desirable. Eventually, though, rsync backups will begin to consume a great deal of space, and after a while you may begin to run out. My solution to this is to periodically mirror my sources and targets, which can be easily accomplished with the --delete option. This option will delete any file from the target not found on the source. It does this after all other syncing is complete, so it's fairly safe to use, but it will require enough drive space to do a full sync before it does its thing. Here's our network command from above, only this time using the --delete flag:

/usr/bin/rsync -az -vv -e SSH --exclude "Archive/Do Not Backup" mac01.systemsboy.com:/Volumes/Work//Volumes/Backups/mac01 --delete --eahfs > ~/Log/mac01-backup-log.txt

Typically, I run the straight rsync command every other day or so (though I could probably get away with running it daily). I create the mirror at the end of each month to clear space. I back up about a half dozen machines this way, all from two simple shell scripts (daily and weekly) called by cron.

Conclusion
I realize that this is not a perfect backup solution. But it's pretty good for our needs, given what we can afford. And so far it hasn't failed me yet in four years. That's not a bad track record. Ideally, we'd have more drives and we'd stagger backups in such a way that we always had at least a few days backup available for retrieval. We'd also probably have some sort of backup to a more archival medium, like tape, for more permanent or semi-permanent backups. We'd also probably keep a copy of all this in some offsite, fireproof lock box. I know, I know. But we don't. And we won't. And thank god, 'cause what a pain in the ass that must be. It'd be a full time job all its own, and not a very fun one. What this solution does offer is a cheap, decent, short-term backup procedure for emergency recovery of catastrophic data loss. Hard drive fails? No trouble. We've got you covered.

Hopefully, though, this all becomes a thing of the past when Leopard's Time Machine debuts. Won't that be the shit?

1. According to the RsyncX documentation, you should not need to do this, because the RsyncX installer changes the command path to its custom location. But if you'll be running the command over the network or as root, you'll either have to change that command path for the root account and on every client, or network backups will fail. It's much easier to simply put the modified version in the default location on each machine.

2. Updates to Mac OS X will almost always overwrite this custom version of rsync. So it's important to remember to replace it whenever you update the system software.

Labels: , , , ,

Scripts Part 6: Archiver

Thursday, November 30, 2006
A hint on MacOSXHints yesterday discussed using tar to create backups in Mac OS X. The poster was frustrated with the OS X-bundled version of the zip command, and confused by the way the Finder creates .zip files. Indeed, the Finder does not use the zip command to create its .zip files, and indeed it is confusing. And, more importantly, the zip command does not preserve all-impotant Mac OS X resource forks.

After reading this hint I was reminded of a script I wrote a while back based on yet another MacOSXHints hint that uses ditto to create Finder-like .zip archives. So it seemed like a good time to post the script here and add it to the waning ScriptSharing series.

So here it is: my Archive script. It will both archive and expand folders or files using ditto, and it places these archives on the Desktop.

Archiver Script
See the code

Labels: ,

Using SSH to Send Variables in Scripts

Wednesday, November 22, 2006
In July I posted an article about sending commands remotely via ssh. This has been immensely useful, but one thing I really wanted to use it for did not work. Sending an ssh command that contained a variable, via a script for instance, would always fail for me, because, of course, the remote machine didn't know what the variable was.

Let me give an example. I have a script that creates user accounts. At the beginning of the script it asks me to supply a username, among other things, and assigns this to a variable in the script called $username. Kinda like this:

echo "Please enter the username for the new user:"
read username


Later in the script that variable gets called to set the new user's username, and a whole bunch of other parameters. Still later in the script, I need to send a command to a remote machine via ssh, and the command I'm sending contains the $username variable:

ssh root@home.account.server 'edquota -p systemsboy $username'


This command would set the quota of the new user $username on the remote machine to that of the user systemsboy. But every time I've tried to include this command in the script, it fails, which, if you think about it, makes a whole lot of sense. See, 'cause the remote machine doesn't know squat about my script, and when that command gets to the remote machine, the remote machine has no idea who in the hell $username is. The remote machine reads $username literally, and the command fails.

The solution to this is probably obvious to hard-core scripters, but it took me a bit of thinkin' to figure it out. The solution is to create a new variable that is comprised of the ssh command calling the $username variable, and then call the new variable (the entire command) in the script. Which looks a little something like this:

quota=`ssh -t root@home.account.server "edquota -p systemsboy $username"`
echo "$quota"


So we've created a variable, called $quota, which is the entire ssh command, and then we've simply called that variable in the script. That $quota variable will have the $username variable already filled in, and the command will now succeed on the remote machine. One thing that's important to note here: generally the command being sent over ssh is enclosed in single-quotes. In this instance, however, it must be enclosed in double-quotes for the command to work. I also used the -t option in this example (which tells ssh that the session is interactive, and to wait until it's told to return to the local machine) but I don't actually think it's necessary in this case. Still, it shouldn't hurt to have it there, just in case something goes funky.

But so far nothing has gone funky. This seems to work great.

Labels: , ,

Send Remote Commands Via SSH

Friday, July 07, 2006
This is one of those "I'm posting it so I remember, 'cause I keep forgetting" posts. It's also astoundingly cool, though, if you didn't know about it. Which I didn't until fairly recently.

If you've ever wanted to send a command to a remote computer without ever actually logging in to that computer, ssh is your friend. Yes, with ssh you can send commands directly to another system. Who knew?

I'll keep this short and sweet. Here are some examples.

The basic form looks something like this:
ssh systemsboy@rhost.systemsboy.edu 'ls -l'


where "systemsboy" is actually your username on the remote host, and "rhost.systemsboy.edu" is your remote system. The command you're sending is contained in single quotes.

Here is an example sending multiple commands:
ssh systemsboy@rhost.systemsboy.edu 'ls -l; ps -aux; whoami'


wherein each command is separated by a semicolon.

Finally, here is an example sending a command that requires user interaction:
ssh -t systemsboy@rhost.systemsboy.edu 'top'


Note the -t flag. That tells ssh that you'll be interacting with remote shell. Without the -t flag top will return results after which ssh will log you out of the remote host immediately. With the -t flag, ssh keeps you logged in until you exit the interactive command. The -t flag can be used with most interactive commands, including text editors like pico and vi.

Sending remote commands via ssh is incredibly handy when writing shell scripts as it allows you to run your scripts locally even if those scripts are meant to effect changes on a remote machine. I just wrote a script, for instance, that sets up vacation mail forwarding for staff members. Without these remote commands I would have had to have staff members log directly onto the mail server and run the scripts from the command line, which I don't think they'd be too happy about. With ssh remote commands, I can give them the scripts and they can run them right from their Desktops. Believe me, they much prefer this.

Credit where due, all information was obtained from Rambo's post. Rambo, thanks. Whoever you are.

UPDATE:
For additional information about using this trick with variables within the remote command, see "Using SSH to Send Variables in Scripts."

Labels: , ,

Scripting Filenames with Spaces: A for Replacement

Thursday, April 27, 2006
Okay, this will be a quickie. Really.

I use for loops in scripts all the time, but for chokes on files with spaces in the name. After years of finding ways to avoid this problem any way I could, I've finally found what I believe to be the solution.

The for command treats any whitespace as a line break. So if you try to use for on a list of files (or folders or whatever) the loop will not function properly on items with spaces in the name. The for command will treat everything after the space as a new item.

Let's say you want to copy every file that starts with "Systems" in the folder "Start" to a folder called "Finish." The "Start" folder contains the items:
Systems Boy
Systems Girl
Systems Baby
James Bond
Bat Man

Using for would go something like this:

for item in `ls Start | grep Systems`
do cp "$item" Finish
done


The for command, however, will treat "Systems" and "Boy" as two separate items, and when the cp command is issued it will complain:
cp: Systems: No such file or directory
cp: Baby: No such file or directory
cp: Systems: No such file or directory
cp: Boy: No such file or directory
cp: Systems: No such file or directory
cp: Girl: No such file or directory

The solution is to forego for and pipe your command to a while read statement like in the following example:

ls Start | grep Systems | while read item
do cp "$item" Finish
done


The quotes around the $item variable are essential. Without them the script will fail in the same way as for. With them, the script works like you wish the for loop did and is able to properly copy files with spaces in the names.

Nice. And by "nice" I mean halle-fuckin-lujah!

I should give some credit for this tip. I originally read about it here at MacGeekery, but didn't quite understand it until I read some posts on various forums. Of course, there's nothing like a real-world problem to solve, and I had this as well to aid my understanding of this method.

Labels: ,

Scripts Part 5: New Spotlight Disabler

Saturday, March 04, 2006
Someone recently commented that my script to disable Spotlight was no longer functioning in v. 10.4.5 of Tiger. When I went to check on the functionality of the old script, I realized I'd been working on a new and improved version awhile back, and that I'd intended to post it, but completely forgot to. So I went in and finished up this spiffy new version, and I'm posting it today for anyone who's interested, or for anyone for whom the previous version had stopped working.

This new version comes with the same disclaimers as the other one (which are now listed in the script itself), but gives you a few more options for disabling Spotlight. In particular, you can now choose to disable/enable Spotlight on either a single volume, or an all volumes. The script will also report the Spotlight status of all currently mounted volumes before asking you what you want to do.

Enjoy!

SpotlightEnableDisable Script
See the code

Labels: , ,

Scripts Part 4: Cloning — What's the Big Deal?

Sunday, February 19, 2006
Boy, there sure are a lot of cloning apps out there. The mother of them all, of course, is Mike Bombich's Carbon Copy Cloner, but it's slowly losing mindshare to more aggressively marketed apps like the affable SuperDuper!. There are others, but I don't feel like scouring the web for them, nor do I feel like going to the effort of linking to them all. Suffice to say, there are plenty. Just search VersionTracker and you'll see.

I find the recent upswing in cloning utilities strange. Apple's bundled Disk Utility application has actually harbored the ability to clone a system disk for some time now (I believe as far back as Panther). And yet, it seems the easier cloning gets, the more apps there are with which to do it. And charge you for it.

Today's script uses a handy command-line utility that's actually been around since the Classic Mac OS days (though not, obviously, in command-line form): asr, which stands for Apple Software Restore. The asr command is essentially a command for cloning disks. In fact, that's exactly what it is. When Mac OS X first came out, asr was not bundled. But in recent incarnations of the OS it's hung around in the command-line, and it's actually gotten quite refined and easy to use. Want to clone your boot drive? Here's the command:

sudo asr -source [source_volume ] -target [target_volume ]


That's it. I can't imagine an easier command structure. In a way, it's almost easier to use than GUI apps that do the same thing. Of course you can get into some very complicated uses of asr, but for basic disk-to-disk cloning it's drop-dead simple.

Now there is one little, tiny bump in this road. Tiger, you see, has a brand spanking new way of making certain files on your boot drive invisible. You know, files like var and etc and private. And Tiger's version of asr (as well as Tiger's Disk Utility program) are none the wiser. So, if you want things set up properly, you need to explicitly set the visibility of these files. There are a few ways to do this. Today's script will use a utility called SetHidden, which comes on the Tiger install disc (a la this Apple KB article). Just so you know.

So here it is. A very simple script for making an exact clone of a volume to another volume. Please keep in mind, because of the file visibility issue, this script MUST be run from the disc image, or it will not work properly. Also keep in mind that cloning will overwrite, replace or even erase the target drive. I am in no way responsible for any damage you incur to your system with this script. If you don't feel comfortable using it, please don't.

That said, here's your free cloning utility.

Download ASRClone

Labels: ,

Delayed ACK Startup Item for Intel Macs

Friday, February 03, 2006
MacFixit just reported about troubles the new Intel-based Macs are having with network speeds, particularly AFP connections to, of all things, other Macs. The solution, they report, is to set the delayed_ack property to 0. In order for this change to survive a reboot, however, they recommend editing /etc/rc. The problem with this is that, often, edits made to /etc/rc will be overwritten by future updates to Mac OSX. In my experience, such modifications are better handled with a startup item, which is also a lot easier to add and remove. So I've suggested as much to the fine folks over at MacFixit, and I've even put my money where my mouth is. I'm offering to those who need it this delayedACK Startup Item, hand made by yours truly.

The linked disc image contains the delayedACK Startup Item, and also includes an installer and an uninstaller for the Startup Item.

Enjoy, you lucky Intel Mac owners (of which, alas, I am not one... Yet...)

UPDATE:
A reader called Nubo recently left this comment:
...turning off delayed_ack is not necessarily something that should be left in the startup items forever. Having it on is normally beneficial or at least not severely degrading in normal environments. So this should be reviewed whenever Apple fixes the underlying problem in its implementation, or the actual root cause is found.

Nubo is absolutely right. This startup item should be removed — either by running the included uninstaller or by simply dragging the startup item to the trash — once the problem has been resolved by Apple.

Thanks, Nubo, for pointing this out.

Download the Delayed ACK Startup Item

Labels: , , ,

Scripts Part 3: Split and Rejoin Large Files

Tuesday, January 31, 2006
Two events have transpired to lead to the posting of this script: 1) I've been meaning to post a new script to the Scripts section of the blog for some time, and 2) MacOSXHints today had a hint about splitting and rejoining large files, and suggesting scripting this process. I just happen to have had such a script lying around for some time, so this seemed like an especially appropriate time to post it.

Essentially, this script is made to take large files and cut them into smaller (theoretically CD or DVD sized) pieces. The same script can then be used to rejoin these chunks. For splitting, the script uses the split command, and to rejoin files, it uses the cat command.

So here it is in all its glory.

SplitAndRejoinFiles Script
See the code

Labels: ,

Scripts Part 2: .DS_Store Remover

Saturday, October 15, 2005
Why do so many Mac folk need a GUI for everything? Sometimes a little script is plenty to get the job done. And using a script can be just as easy as using a GUI: it's double-clickable; it's instructive; and it's drag-n-drop. It just doesn't have pictures. But for some reason people still freak out when they see that big, scary, text-based Terminal pop up. I used to be that way. But I've grown to love the power of the command-line, and simple shell scripts.

So here's another popular favorite: The .DS_Store Remover utility. There seem to be billions upon billions of little apps that do nothing but remove the .DS_Store files that the Mac OS puts in every folder on your system. Maybe there are so many of these little apps because it's actually such an easy thing to script. The nice thing about the script is, you can see and modify the code very simply and easily, whereas with one of these GUI wrappers, God knows what it's actually doing.

For those who don't know, the .DS_Store file holds information about how a given folder should display when it's opened. It remembers the position, size and view style (i.e. column, list or icon) of the window. Why remove them, you may ask? Some people don't like them showing up on their windows boxes, apparently. Too messy. Ahh, if only I could write a script to delete Windows boxes. That seems like the better approach.

Anyway, here's my script version. I call it "DSStoreRemover," which frankly I think is possibly the most ingenious and creative name for anything ever in the history of humans on planet Earth.

It's a really, really, drop-dead stupid simple script that takes a folder path as a variable which is used in a find command that then, in turn, executes rm on anything named ".DS_Store."

See, you don't need a GUI for this. Hell, you almost don't need a script.

.DS_StoreRemover Script
See the code

Labels: ,

Scripts Part 1: Maintenance

Saturday, September 24, 2005
I see a lot of shareware applications out there, and some of them are great, but then some of them make me think how easy it would be to write a simple shell script to do the same thing they do. The primary advantages here are twofold:
1) The script, as opposed to the application, is free.
2) The script can be run from the command-line, and, therefore, remotely.

If either of these advantages are more a concern to you than a pretty wrapper around what is essentially a series of shell commands, then this series will be for you. I have been writing a lot of what I think are pretty useful little scripts. These scripts are stupid simple, and I really make them so I don't have to type out a bunch of commands to do certain things, and so that I don't have to scour man pages for syntax when I invariably forget the proper way to write out a command.

I am by no means an advanced scripter, and I'm sure folks can find lots wrong with my scripts, and lots of ways to do things better. And that's great. I really want to learn more -- and better -- scripting methods. So feel free to leave suggestions on the site in the comments section.

Here is the first of many featured scripts. It's a really simple idea inspired by one of the bajillon shareware dealies out there that does what they call "maintenance:" It runs daily, weekly, and periodic maintenance, it will update your system's prebinding, and it will repair permissions. This script does exactly what many of those apps (essentially, GUI wrappers) do, but instead of giving you buttons and checkboxes, you get to enter text in the shell, which, I promise, will make you feel a hundred times cooler. Well, in the geek sense of the word, anyway.

So here it is, for your pleasure. Look for more scripts on an irregular basis in the near future.

Multi-Maintenance Script
See the code

Labels: ,

Why We Need Anti-Virus Software for Mac

Sunday, September 11, 2005
I recently wrote a review of the excellent antivirus utility, ClamXav. I also read constant articles and hear constant debate about whether or not you need virus protection on the Mac. I used to be in the camp that says, "There are no viruses for Mac, so why use antivirus software?" But nowadays, I find myself in the other camp, the one that says, "Of course we need virus protection on the Mac, you idiot."

To be honest, I was never as cavalier as to suggest that no virus protection was ever needed on Macs. But we Mac folk are in an interesting predicament (though not as interesting as our Windows-using pals): Currently no viruses directly affect us, and antivirus software for Mac is, by and large, abhorrent. In fact, it is far more likely that your system will be adversly affected by antivirus software than it will by a virus. To wit, Norton Anti-Virus has frequently caused numerous problems on client Macintoshes I manage in my freelance duties. Moreover, many antivirus software packages install kernel extensions, which is the surest way to hose a system. Even Apple recommends against it to developers, citing kernel extensions as a last resort. I frankly don't understand why antivirus software would have need of kernel extensions, given that all it really needs to do is scan files and compare them against a list of known viruses, but apparently the Norton folks think this is important. And it's been wrecking people's systems.

So, the state of things being what they are, it's no surprise that Mac users just go, "Fuck this," and ignore the problem, or worse, deny it. I mean, what else is a poor Mac gal or fella to do?

Let me back up here and explain why I've switched camps. There are two reasons, actually. One, I work in a very heterogenous network, and I see the effect Windows viruses can have on our systems. And on our Windows admin. It's hellish. And it's a problem that, while I don't personally suffer from it, I certainly don't want to contribute to. Macs can and do spread viruses to other computers. I've seen it happen. At this point I could launch into a whole number about how we're all citizens of the internet, and how it's our responsibility to be good ones. But I won't. Instead I'll tell you my second reason for switching camps: I got a virus. Yep. Sure did. This virus (actually, I think it was a worm, but we'll treat all such programs as "viruses" for the purpose of this article) was passed to me, I believe, by a Windows user inside a Word document. Unfortunately, I needed this document, and I needed to send it back out to other Windows users. Fortunately, I had a trusty old copy of Norton Anti-Virus and an OS9-bootable system from which to do the repairs. But if I hadn't, I would not have been able to use the document. If my job had been dependent upon that document... Well, you can extrapolate. Unless you're planning on never sharing files with anyone other than Mac users -- ones who also only share files with other Mac users, by the way -- you do have to worry about viruses. Just not as much as Windows users. Here I like to paraphrase the AIDS prevention folks: When you're sharing files with someone, you're sharing files with everyone they've ever shared files with. And the internet is, like, one big, giant file-sharing orgy. Do you really want to be running around out there without a condom?

Me neither.

I don't want to get too much into the options. This is more an explaination of why we Mac kids do actually need some form of virus protection. But I will quickly tell you what I do, and why I've settled on my method. My method is the ounce of prevention method. I use ClamXav on my systems and do weekly scans. Also, using ClamXav's new "Sentry" feature, I have a few watch folders: my mail, my downloads folder, and any folder I might be sharing on my LAN. (Keep in mind here that ClamXav does not scan subfolders, for performance reasons.) This pretty much covers most of the bases. If you get ClamXav set up right, you should be in real good shape when it comes to detecting viruses. Unfortunately, ClamXav does not repair viruses. So if you already have one, or if, God forbid, one should squeak by, you'll need something to fix it. I'm lucky. I have my old OS9-Norton system. But these are becoming almost as rare as Mac viruses themselves. If you have a virus now, you should quarantine all instances of that puppy, go do some research, and find the least invasive, non-kernel extension installing antivirus repair software you can. If you can run it off the CD without installing anything, all the better. Otherwise, just wait. Yeah, you heard me. Wait. The chance that you'll get a virus is pretty slim, and it's quite likely that, by the time you do, any virus software you buy today will be out of date, obsolete, or just plain useless. So wait, and if a virus ever rears its ugly head on your system, then go buy something to fix it. Oh, I might also suggest that if the antivirus software does have to be installed on the system, you might want to use a spare firewire drive for the install, provided you have one, of course. I like to have a lean, bootable OSX system on a small firewire drive, install the antivirus software there, and boot from this drive when I have a problem. That keeps my primary boot drive clean of antivirus cruft.

So that's what I do. And that's what I think. And so far, it's worked pretty well. The only thing that kind of breaks my flow is when freelance clients freak out and install Norton AV on their systems without asking me about it first. Ever try to remove that shit? Holy Hell. Thank my lucky stars for this uninstall script, but until I found it, it was murder.

Okay, kids. Time to go put a helmet on that soldier.

Labels: , , ,

Tiger Lab Migration Part 7: Wiggly-Niggly

Well, we're getting close. We're down to last, wiggly-niggly little tidbits. Here's where we've been in the last few weeks:

The Master System
We have completed a very nice build of Tiger with most of the software we need on all machines, though we're lacking all the most recent Adobe stuff due to not having received the most recent Adobe stuff. 'S'okay. We'll make do with CS1 for now. Our system is all loaded up with our custom scripts, and a new, beefier home account mount script. And it's got a nice, big, 75GB system partition. Why, it's just swell.

We've used this system to clone to all our other lab machines. We boot these other machines in firewire target disk mode, and then we use Disk Utility to restore the Master System to the new machine's system partition. Or, we wanted to use Disk Utility. Turned out that our first Disk Utility-cloned system had some problems due to -- yep, you betcha -- Tiger bugs. The problem was that Disk Utility wasn't blessing the new system partition, so when we'd boot the new machine, we'd get the flashing question mark of doom. So we'd have to then boot off the Tiger install disk, and set the new system partition on the newly built machine to be the startup disk. I decided this was a pain, and that it would be much easier and more instructional to do our clones with a tiny, tiny shell script that calls ASR (Apple Software Restore, via the asr command).

#!/bin/bash

## Script to Clone Local Volumes ##
## systemsboy - Aug 18, 2005 ##

clear

## Define Variables ##

echo "
Please enter the path to the SOURCE volume or ASR-ready disk image...
(Example: /Volumes/MyVolume)"
read SOURCE

echo "
Please enter the path to the TARGET volume...
(Example: /Volumes/MyVolume)"
read TARGET

## ASR Portion of Script ##
echo "
Building Clone... Please wait...
________________________________
"
sudo asr -source "$SOURCE" -target "$TARGET" -erase

exit 0


This did the trick indeed, and was as easy to use, if not as purdy, as the Disk Utility application. This method only yielded one problem, and that was that all the invisible folders -- /var /etc /private and the like -- were not made invisible on our cloned systems. This is another Tiger bug, but one that was fixed in 10.4.2's version of Disk Utility. Apparently not fixed in ASR from the command-line, however. This problem yielded both an intersting solution, and some interesting information. Back in the day, these files were made invisible to the Finder by the magic of the .hidden file. The .hidden file was simply a list of files or folders at the top level of the root drive that should be treated as invisible by the Finder. Want to make something invisible on /? Just add it to the .hidden file and restart the Finder. (Ironically, the .hidden file was also at the root level of the system, but was rendered invisible by the fact that its name began with a period.) Nowadays, however -- in Tiger, that is -- this is no longer that case. Files on root are now made invisible, according to this Apple KBase article, by setting certain file attributes. I'll tell you, I have yet to figure out what those attributes are, or how to modify them, but when I do I'll shout. In the interim, I was forced to locate the "SetHidden" program on my original Tiger install DVD. After insering the DVD, it can be found at:
/Volumes/Mac\ OS\ X\ Install\ DVD/System/Installation/Packages/OSInstall.mpkg/Contents/Resources/

I've now copied this file to a folder called SetFile, which I've placed in the Applications folder for future use. Also, I needed the hidden_MacOS9, which can be found, and should be placed, in the same folder as the SetHidden command. So I now have a folder in my Applications folder, called SetHidden, in which the SetHidden command and the hidden_MacOS9 files reside, installed on my master, and I've added the commands:
cd /Applications/SetHidden
sudo SetHidden /Path/To/My/Clone/System hidden_MacOS9

to my shell script, and voila! Clone script complete!

#!/bin/bash

## Script to Clone Local Volumes ##
## systemsboy - Aug 18, 2005 ##

clear

## Define Variables ##

echo "
Please enter the path to the SOURCE volume or ASR-ready disk image...
(Example: /Volumes/MyVolume)"
read SOURCE

echo "
Please enter the path to the TARGET volume...
(Example: /Volumes/MyVolume)"
read TARGET

## ASR Portion of Script ##
echo "
Building Clone... Please wait...
________________________________
"
sudo asr -source "$SOURCE" -target "$TARGET" -erase

## Set Hidden Files (Tiger Bug Workaround) ##
echo "
Mac OS X 10.4 does not properly set hidden files.
We will now use the SetHidden command to rectify the problem.
For this step, the SetHidden folder must be present in /Applications.
---------------------------------
"
cd /Applications/SetHidden
sudo ./SetHidden "$TARGET" hidden_MacOS9

exit 0


Cloning all 14 systems on the floor took my Lab Assistants a few short hours.

Spotlight
I mentioned some concerns regarding Spotlight and the particular way in which users use our lab. After some mucking around, and testing of various methods of disabling Spotlight, both forced and optional, I've decided to do nothing. I do this kind of thing all the time. Worry and worry about something, and then, finally, throw caution to the wind and do nothing about it. It's my way. It's part of what makes me so gosh-darn lovable. But I do have two things behind that decision: a rationale, and a backup plan.

The first problem I'd anticipated was that Spotlight would begin indexing user home accounts over the network all at once as soon as everyone logged in, and that this would cause problems with network performance and incomplete indexes. Upon further reflection (read: obsessing), I decided that that Spotlight's network resource usgae would probably be low, and that it would probably avoid incomplete indexes by either continuing in the background after logout, or by resuming at next login. Also, since home accounts have quotas, the largest of which is 7 GB, indexing shouldn't take too long, and any problems should be quickly mitigated.

The second possible problem I'd worried about was that Spotlight's insistance on indexing firewire drives would take forever to yield complete indexes on large drives -- a process that would likely be interrupted at logout before it was complete -- leaving many users with partially indexed drives. In my tests, however, Spotlight picked up right where it left of with drives that were partially indexed when ejected and then re-mounted, so I'm not convinced this will even be a problem. I also worried that Spotlight's firewire drive indexing would cause performance problems that would incapacitate users who were working on video. This may yet be the case. We'll know soon enough.

I came up with a number of possible solutions to these problems, all messy, all imperfect. Ultimately, I decided that the best option was to wait and see what problems arose, and then tackle those problems with the most appropriate of the solutions I devised. Who knows? Maybe it will all work out great without any intervention from me. And that'd be just ducky.

Network
We have an intersting and complex network. It consists of Mac, Linux, and Windows machines, a network RAID, and web and mail storage. And all of this is accessible, in one way or another, via the network. The problem comes when you try to explain all this to new (or sometimes even old) students. It's not an easy picture to paint. And overwhelmed first years usually don't quite catch on for some time. But as we design our network, and build our systems, we're very concerned about how all that is presented to the users. And we try to make it as simple and as understandable as possible, which is, after all, the Mac way, and is why people love the Mac. So let me just say, right here, right now, what the fuck is up with the "Network" view? That piece of shit gets worse with every OS revision. And no one seems to care. I can't find diddly about it on the forums.

So here's the background on this outburst. Back in the Panther years, the Network view offered up a pretty nifty way to present a great deal of our network -- the shared drives of all platforms -- to our Mac users. The coolest part was that it looked much like what you saw on Windows, which simplified things greatly by presenting a consisten network view across platforms. There were a couple things that made this possible. One was SMB workgroup names. SMB does a great job of not only sharing files, but broadcasting itself as a service on a network. Setting up computers under SMB with a workgroup name based on the platform of the given machine got all our Mac, Linux and Windows computers grouped appropriately on the network. And Mac can read those groups and smartly creates folders in the Network directory named after those groups and populated with the systems that belong to them. So in my Network browser, there'd be a folder called "Linux," and all the Linux computers would be in there. Same for Windows. Here's the catch: Our Macs share via SMB to Windows, but we want them to share via AFP to other Macs. Personal File Sharing, which uses AFP, does not, by default broadcast any kind of grouping. If you turn on AFP, you just broadcast the service, but you can't specify it's appearance or where on the client the shares will appear. Computers broadcast via AFP in Panther just show up in the "local" folder, not in a "Macs" folder like their SMB sharing counterparts. There was, however, a sneaky way to define this in Panther, by editing a little file called /etc/slpsa.conf, and thereby magically creating what are known as SLP scopes. In fact, SLP scopes are just that -- a way to group a particular service from a particualr device into logical groups. So we scoped our Macs to the "Macs" scope and they showed up in our "Macs" group in /Network, and all was well in the universe. If you're unbearably astute, you'll probably be wondering why, though, our Macs, when connecting to other Macs via the "Macs" scope in the Network folder, didn't connect to said Macs via SMB rather than AFP. And here was something amazingly cool in Panther. Panther smartly dealt with the folder full of Macs in our Network view. So, when it saw these other Macs broadcasting and sharing over two protocols -- AFP and SMB -- it intellegently chose the best one, which for a Mac was AFP, of course. That was the thing of beauty that allowed us to present the same view of the entire, heterogeneous network the same way on all platforms while still allowing us to connect with different protocols. It was frickin', frackin', goddamn sweet, is what it was. Brilliant. And now it's gone.

Not only is this intelligent decision making gone from Tiger, at least in the latest incarnation (10.4.2 as of this writing), but so too is the ability to define SLP scopes. So, this means two bad things: 1) I can no longer define specific locations for my AFP-shared Macs, and 2) any connection made via the "Macs" folder in the Network folder (which, remember, is now only defined by SMB, not by SLP) connects via SMB; my Macs connect to each other via the Windows file sharing protocol, which is a big fat problem.

So, I'm currently trying to devise a way to scope the Mac shares into some sort of logical grouping that will allow me to present those shares in a palatable way. But it ain't easy. I know you can do this with Tiger Server, and this is probably why they've crippled it on the client, but I don't a Tiger Server yet, and I'm hesitant to build one this close to the beginning of the semester. So we shall see...

The migration is nearly complete. Time permitting, I would abasolutely love to build a fresh new Tiger Server. I'll probably give it a shot in this last week before classes begin, but I'll be sure and keep a clone of the existing Panther Server in case things go awry. Beyond that, and the aforementioned wiggly-niggly, we're done. We're upgraded, on the workstations anyway. And it is good.

There will, most likely, be problems that arise once the students come in and start using the new systems. I will share those in a later post. Until then...

Labels: , , , ,

Automounting NFS Home Accounts

Thursday, August 11, 2005
In the lab where I work, we have networked home accounts for all our Mac users. These accounts live on an NFS RAID on another, non-Apple machine. This, as they say, "took some doin'," but we've had it working very reliably for some time now. It's a neat process, and one I'm rather proud of figuring out. So I thought I'd write a quick (yeah, right!) explaination of what we do.*


General Overview
Generally speaking, in our setup, three things need to happen:
1. The client must be set up to bind to the MacServer with the Directory Access application.
2. The client must automount the NFS RAID at startup so that home accounts are available for the user.
3. The MacServer must authenticate the user and specify where her home account is mounted.


On The NFS Server
I do not administer our NFS RAID. I am not an NFS expert, but I can tell you what I do know:
1. For our purposes, the entire directory containing the user accounts must be exported.
2. Root, I believe, should be mapped to root. It is crucial that the client system have root access to the NFS export.
3. Most typical NFS setups should work withouot a great deal of tweaking, but, if I remember correctly (it's been awhile since we set this up), that last root thing is a deal breaker.


On The Client
The client needs a couple things done to it:
1. The client must be bound to a properly configured MacServer (see below), using the Directory Access application. Most folks who've set up networked home accounts know how to do this. If you don't, read the manual. It's not hard.
2. The client needs to mount the NFS share, preferably at each startup. And this is where the fun begins. Our goal here will be to create a custom StartupItem that automounts our NFS export at each boot.**

For purposes of this example, we'll call our local mount point /home, and our NFS export we'll say lives at the IP address 192.168.1.100 in the folder /Users/Home. (If you're following along at home, feel free to substitute your own values for anything provided in these examples.)

To mount our NFS server, we use a command called automount. automount is sweet, and you can do a lot with it, which we'll get to in a minute. For now, a command you may want to use to test your NFS setup before adding startup scripts and whatnot, is the mount_nfs command, and it looks something like this:
IPaddress_of_NFSShare:/path/to/share /local_mount_point

Don't forget to create that local mount point directory first:
sudo mkdir /home

So, for this example:
sudo mount_nfs 192.168.1.100:/Users/Home /home

This is a good command to use for temporary mounts of the NFS export. Anything mounted this way will unmount after reboot. Or you can simply use:
sudo /umount /home
to umount the NFS share.

Now let's get into automount.

One of the cool things about automount is that it uses maps to call NFS and other shared disks. Once you've established a startup procedure, you can use maps to add, remove, or change your automount setup. This is handy if you're using scripts (which we are) because it means we really shouldn't have to ever change our scripts. Any changes can happen to the maps and are easy to do. The automount map file looks like this:
home rw,net,tcp 192.168.1.100:/Users/Home

The first field specifies the local mount point, the second field specifies NFS options (these work best for us, your mileage may vary, but the rw option is necessary and the net option is recommended), and the third field is the NFS export. Place these values in a space-delimited, plain text file, and call it something you'll remember. For our example we'll call it MyMounts. (Do not use a .txt file suffix on this file. Doing so will break all the examples to come.)

automount syntax is fairly simple, if confusing at times. It looks something like this:
automount -m /mount /path/to/mymounts
where /mount is where the NFS mount will be mounted. The -m flag tells automount to use a map file, the path to which is specified in the second argument to the command. automount then reads the map file, and grafts the home mount point to a symlink inside the directory /mount.*** So, with your NFS server properly configured, and your MyMounts file on your Desktop, if you do this:
sudo automount -m /mount ~/Desktop/MyMounts
You should see your home mount appear in the
directory /mounts. In Tiger, however, this initial mount point does not show up in the Finder. To see it, you must type "command-shift-g" and type /mount in the text field. Or you can look in the Terminal with:
ls /mount
You should also see the mount point listed when using the df command in Terminal. If you don't see the /mount with home inside, something is wrong. You need to troubleshoot your NFS setup. If the share is there, move on to the next step.

Once you've got automount properly mounting the NFS export, it's time to create a very simple StartupItem to handle all this at each boot automatically. This is about the simplest StartupItem imaginable. You need three files:
1. A simple shell script
2. Your MyMounts file
3. A StartupParameters.plist file
Put these in a folder, which we'll call MountNFS.

If you're following along, you have the MyMounts file already, so that's done. Put it in the folder. Next, let's make the StartupParameters.plist file. This file just specifies a thing or two about how the startup item should run, and what messages it will generate. Copy and paste the following text into a plain text file, call it StartupParameters.plist, and save it to your MountNFS Folder:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>Description</key>
<string>Automount NFS</string>
<key>Messages</key>
<dict>
<key>start</key>
<string>Mounting NFS</string>
<key>stop</key>
<string>Mounting NFS</string>
</dict>
<key>OrderPreference</key>
<string>Late</string>
<key>Provides</key>
<array>
<string>AutomountNFS</string>
</array>
<key>Requires</key>
<array>
<string>NFS</string>
</array>
</dict>
</plist>


Finally, we need the shell script, which simply looks like this****:


#!/bin/sh

##
# Automount NFS Export
##

. /etc/rc.common
ConsoleMessage "Automounting NFS"
rm -rf /home
automount -m /mount /Library/StartupItems/MountNFS/MountNFS
ln -s /mount/home /home


Copy this text into a new plain text file, and save the file as MountNFS (it must be the same name as the folder, and it must not end with a .txt or any other file suffix). Make sure it is executable:
chmod 755 ~/Desktop/MountNFS/MountNFS

So, this folder, MountNFS, becomes your actual StartupItem. At this point, you probably want to have this thing run at startup, and the way to do that is to place the MountNFS folder in /Library/StartupItems. (If the StartupItems folder doesn't exist, create it.) You should also set permissions on the MountNFS folder and its contents as well since Tiger will complain (and then kindly fix things) if there are any errors. The permissions should be set so that the owner is root, the group is wheel, and (I think) permissions on all files can be 755, so:
sudo chown -R root:wheel /Library/StartupItems/MountNFS
sudo chmod -R 755 /Library/StartupItems/MountNFS

Once NFS and automount are working properly together, and this StartupItem is in place, all you need to do is reboot your client Mac. You should see your NFS share mounted at /home. (If Tiger complains that the permissions are wrong after the first reboot, tell it to "Fix" the problem and reboot again. It's just making sure the permissions are secure, and if all's good, your StartupItem should work ever after.)

Congratulations! That was the hard part.


On The MacServer
As I said, home accounts for our Mac users live on a RAID which is shared via NFS. Authentication is handled (at present) by a MacServer. Briefly, this is what happens when a user logs in to one of our Macs:
1. When the user types in her username and password, the information is sent to the MacServer, which authenticates the user.
2. The MacServer also specifies where the home account of the user is located on the client machine, in our case, the NFS mount point /home.
3. The client allows the user access to the workstation, and places them in the home directory specified by the MacServer, which, again, is our NFS mount point /home.

This involves a little voodoo on the MacServer. Our MacServer users have their home accounts set in a way slightly different than what is generally done on OSX Server. Usually the home accounts are set to AFP or NFS shares that reside on the MacServer and that get automounted by the client. In this scenario, three fields are populated in the Workgroup Manager's home account settings for any given user. Go to the Home tab for any user, and click the edit button (the one that looks like a pencil) to examine these fields. The first field specifies where on the server the home account lives. The second field specifies the name of the folder for the home account (usually just the user's name). The third field specifies where on the client the home account will mount. In our setup, there is no AFP or NFS share on the MacServer itself, so the first two fields are irrelevant. The only field we need to concern ourselves with is the third field -- the one that tells the client machine where to find the user's home account. And all we need to put here is the absolute path to the mount point of our NFS share, which, by our example, would be /home/username. (Subsequent users can have their home directories indicated by simply selecting the new home location that gets created after setting this up. The "username" is assumed by Workgroup Manger, and does not need to be added for each user.)

That's it. Done.

If you've got all this set up properly, you should be able to reboot your client and log in to your Mac as a networked user whose home account is actually located on an NFS share on another computer. It's what we do, and it works great. And it allows us to centralize our Mac and Linux home account locations. Windows is another story. But we're working on it.


* NOTE: These instructions are for Tiger client authenticating to Panther Server. If details change when we get Tiger Server, I'll post them here.

** There is a simpler, though less elegant way to do all this if you don't feel like creating your own StartupItem. You can edit the existing /System/Library/StartupItems/NFS/NFS script. To do this, add the line:
automount -m /mount_point /path/to/mount_map
at the end of the "Start the automounter" section. This may, however, cause problems in Tiger client as the mount may not show in the Finder. Symlinks can be created here, as they are in our script, to alleviate this problem. The other problem with this is that system updates may overwrite this edit, causing you to redo everything. So I strongly recommend the custom StartupItem method outlined above.

*** Clever readers may notice that this method precludes mounting an export in a top-level directory in /. Unfortunately, using automount, the only way I've gotten it to work is by mounting the share inside the directory specified in the command, so if you want your share at the top level of the file system -- i.e. in / -- you'll have to symlink it. This is what we do. It works fine in Tiger (in fact, in Tiger the initial mount point -- in this case /mount -- doesn't appear in the Finder), but we had problems with this in Panther. In Panther we just used the nested mount point and lived with it.

**** This is the script we use for our Tiger clients. Tiger will not reveal the original mount point specified in the script in the Finder, so we use a symlink to the mount point for our actual home location. This is why you see symlink creation in the script. The first line destroys the symlink before recreating it at boot. If this doesn't happen, a broken link could interfere with the script. And, BTW, the symlink method was unreliable in Panther.

Labels: , , , ,

Getting Back to (Search) Basics

Sunday, May 29, 2005
NOTE: A new and improved version of this script has been posted. Please use the new version. It's way better.

First, a few brief DISCLAIMERS:
1. The information and script provided in this post will disable Spotlight indexing.
2. It will also (optionally) erase your Spotlight index.
3. This means that if you want to re-enable Spotlight indexing, you will have to wait for the index to rebuild, which can take a long time.
4. This method only disables Spotlight indexing for firewire drives that are present when the script is run. Once a firewire drive has had Spotlight disabled, it will be disabled forevermore on all systems, as the indexing status of any given volume is stored on the volume itself.
5. Finally, it has come to my attention that using this script to disable Spotlight indexing will also disable searching by "Entire Contents" in Apple's Mail app. (Searching by "From," "To," and "Subject" all work fine.) This is a major drawback for some, and less so for others, but it's something you should be aware of before you proceed to disable Spotlight indexing on your system. If you can't live without Mail searches by content, do not use the script at the end of this post.

These are the only issues I am aware of regarding this script. If you discover others, please post them in the comments section.

And away we go!

I really miss the old Panther-style, find-by-name searches. (And apparently so do a lot of people!) I use them much more than the Tiger method of searching by metadata and file content, which just returns way too many results for my tastes, generally speaking. (I mean, if you don't know the name of your file, how do you know you've found it anyway, right?)

Ideally, Apple would have (or still will, I hope) given us some options here. I think it would be best if searches from the toolbar functioned as they did in Panther (i.e. quick 'n' dirty seach-by-name-in-current-folder) or there were a preference for how toolbar searches work. Spotlight searches should function differently, based on the metadata concept. That's basically how I think it should work: two search methods; two types of results. And bring back the old Finder toolbar search. I love(d) that thing!

That said, I've spent some time researching the matter, looking for a way to get back search-by-name functionality, since, if I have to choose between one way or the other (and right now it looks like I do), I choose to search by file name. I found some tasty info on Apple's Tiger discussion forums which I will briefly outline:

1. Moving all volumes to the "Privacy" tab of Spotlight's preferences will disable Spotlight. However, you will then lose the ability to find files at all -- by name or otherwise -- in the Finder. Also, if you mount an external drive, Spotlight will try to index it until you then add it to the "Privacy" tab. Not the best solution.

2. Spotlight can be completely disabled by simply adding the line:
SPOTLIGHT=-NO-
to your /etc/hostconfig file and rebooting. This method is very thorough, it seems. Drives later added to the system will never be indexed. Spotlight won't even try. Unfortunately, this method again has the side effect of rendering all disks unsearchable from the Finder. Not what I'm looking for.

3. Enter mdutil. (And, BTW, I want to credit Ondrej Zacek from the Apple Discussions. Though the info is freely available, it was his "Finder will fall back to old behavior when searching..." comment that gave me hope. Thanks, dude, whoever you are.) Using mdutil to disable Spotlight indexing on a given volume results in Finder and Spotlight behavior I can live with. Essentially, that is, after you've disabled indexing with mdutil, you can search files in the Finder or with Spotlight, and the results returned will only be ones that include your search term in the file name. And in Spotlight searches, you still get the extra added benefit of having things sorted by type (somehow Spotlight can still identify and sort files by type, even if the search is only by name).

Now that's pretty durned cool. I have the ability to search by name (only) again, and I still get some of the usefulness of Spotlight. (And, P.S., Finder toolbar searches will also be sorted by kind. A simple window style change to list view -- or command-2 -- will get you the flat list you're used to.)

Anyway, here is the one command that will disable Spotlight on ALL your volumes:
sudo mdutil -i off / /Volumes/*

Additionally, you might want to remove the existing databases from all volumes as well, for good measure:
sudo mdutil -E / /Volumes/*

NOTE: Before you run either of these, be aware that if you want to reverse this process you can, but you will have to wait for Spotlight to reindex all your volumes again, and this can take a looong time. Also, if you add an external firewire drive, Spotlight will try to index it. Running these commands will stop it, however.

And, so, to reverse the process:
sudo mdutil -i on / /Volumes/*

A few seconds after running this, Spotlight will begin reindexing.

Finally, some scripting goodness. I wrote a simple shell script that automates all of this. It has options for both enabling and disabling Spotlight metadata searching. Feel free to use it, or modify it, to your heart's content. Ideally there would be a way to run the mdutil commands whenever a firewire drive is mounted, but I haven't tried that yet. In any case, this works really well for me at this point. Hopefully someone else will find it useful as well.

To use this script, open TextEdit (in the standard Rich Text mode, for now) copy the text below "Begin Shell Script" (starting with #!/bin/bash) into a new text file, and then convert this file to plain text (Format->Make Plain Text). Name it, save it, chmod it to 755 (open Terminal, type chmod 755 and then drag the file to the Terminal window and hit return). Finally, drag the file again into the Terminal window, hit return and follow the instructions. Also, if you want to make it double-clickably executable, give the name a .command suffix. Yum!

Hopefully Apple will give us some flexibility in how we search our files in the not-too-distant future. Until then, I'll be using my trusty script and old-world search methods in my shiny new Tiger Finder.

Hmph!

-------------------------
Begin Shell Script
-------------------------
#!/bin/bash

clear

echo "
############# DISABLE OR ENABLE SPOTLIGHT #############"

echo "
This script will enable or disable Spotlight searching
and (optionally) indexing on ALL LOCAL VOLUMES.
Panther-style finds-by-name will still function after
disabling Spotlight using this script.
"

echo "
Choose your poison...

[1] Disable Spotlight
[2] Enable Spotlight
[Ctrl-c] to Quit at any time
"
read poison

if [ $poison = 1 ]
then

echo "


####### DISABLE SPOTLIGHT ROUTINE #######"

echo "
Disabling Spotlight for all volumes...
"
sudo mdutil -i off / /Volumes/*
echo "
Would you also like to erase the Spotlight index (Y/N)?"
read index
if [ $index = y -o $index = Y ]
then
sudo mdutil -E / /Volumes/*
fi
echo "

*********************************************

Spotlight search is no longer in effect.
You may now search by file name only.

Have fun with your Tiger, Tiger.

*********************************************

"
exit 0

else
if [ $poison = 2 ]
then
echo "


####### ENABLE SPOTLIGHT ROUTINE #######"

echo "
Enabling Spotlight for all volumes...
"
sudo mdutil -i on / /Volumes/*
echo "

*********************************************

Spotlight has been enabled on all volumes.
Indexing should begin momentarily.
It may take quite some time to complete.

Have fun with your Tiger, Tiger.

*********************************************

"

else
echo "
You did not choose from the available options.
Please rerun the script to try again.
"
fi
fi

exit 0

-------------------------
End Shell Script
-------------------------

Labels: ,