PDA

View Full Version : auto-disconnect "server" after copying files


digSD
05-09-2007, 12:37 PM
When doing a scheduled backup over a network (to a disk image), SD! will correctly connect to the "server" (as needed) and mount the disk image file (as needed).

Is there a SIMPLE way to disconnect the "server" after SD! is finished copying? Not the disk image (that gets ejected/unmounted automatically), but the "server" itself...

If the connection is left active but the server goes "off-line" sometime later, the Mac with SD! spends a lot of time looking for the "server" at that point, which is what I am trying to avoid.

I tried an AppleScript in SD! to disconnect the "server" "after copying is finished" but that doesn't work because SD! tries to execute that script while the disk image is still mounted.

Thank you.

dnanian
05-09-2007, 05:01 PM
There are some examples on the forums of this kind of thing. Basically, you'd need to use a "shell script" and put that in the background, waiting 30 seconds or so for the backup to fully complete...

afragen
05-09-2007, 06:24 PM
I've written a shell script that will do something just like this. What it does is check the MAC address of your current router. If that MAC address has changed then it will force dismount any AFP mounted disks and maybe any SSHFS mounted disks. I have this script run every minute via a launchd process that I set up with Lingon. The script will log its activity if you set it up that way. Here's the script (http://thefragens.com/pub/unmount.zip). If you have any problems let me know. I've been running it here for over a month without problems.

I've name the script 'unmount.sh' Let me know what you think. If you have problems with it.

Andy

digSD
05-10-2007, 01:03 AM
There are some examples on the forums of this kind of thing. Basically, you'd need to use a "shell script" and put that in the background, waiting 30 seconds or so for the backup to fully complete...

Thanks. Sadly I know nothing of "shell scripts" and only a bit more about AppleScripts (apples and oranges?). A search of the forum did not reveal what I wanted. Oh well.

digSD
05-10-2007, 01:16 AM
I've written a shell script that will do something just like this. ... Andy

Thanks, Andy. As I said above, I don't speak shell scripts unfortunately. My situation is a bit different: the MAC address doesn't change, but the Mac containing the backup disk (which has file sharing turned on) goes to sleep after backups finish (overnight). Since the server icon is left on the desktops of the other Macs by SD, I get spinning beach balls until OSX decides to offer to "disconnect" the server, which can take a while and is most annoying. The only way to avoid this is to get in the habit of remembering to select and eject the server each time I wake up one of those Macs, before doing anything else.

If only SD would disconnect the server (after unmounting the disk image file)... IOW if it could just reverse the procedure it does before copying...

Not sure I'm making myself clear. It's just an annoyance factor, nothing more.

dnanian
05-10-2007, 11:30 AM
The script the user has provided can do this for you... I do understand what you want, but there are issues there that make this more difficult than you might expect at first...

afragen
05-10-2007, 07:40 PM
This script will do exactly what you want. I think. :)

#!/usr/bin/env bash

sleep 45

if [[ `mount | awk '/^afp_/'` != "" ]]; then
# http://www.macosxhints.com/article.php?story=20051107175256782
mount | awk '/^afp_/ { system("umount -f " $3) }'
echo $now "afp disk unmounted"
fi


Save it and set it to executable. You'll then have to call it from within SD's Advanced settings to run the shell script after copy completes.

Dave, if you want to include this script with SD feel free.

Andy

dnanian
05-10-2007, 09:48 PM
Well... this won't handle SMB mounted drives and assumes that there's a single network volume attached. But I appreciate the post, and hope others will find it useful.

As an aside, I can't tell you how happy I am to see members of the SuperDuper/Shirt Pocket community contributing solutions. It's really greatly appreciated: thanks to everyone who's chipping in!

digSD
05-10-2007, 10:13 PM
Preliminary testing shows this does indeed work for me. Thank you!

afragen
05-11-2007, 01:30 AM
You're welcome.

afragen
05-11-2007, 01:37 AM
What can I say, I don't have an SMB mounted drive. If you can provide me with the results of a 'mount' command with and SMB mounted drive I'm sure I can adapt the script for that as well.

You could always loop the unmount commands through a loop for the number of AFP or other mounted drives. I'm fairly sure some sort of grep command can count the number of hits to that particular search string.

But I do understand that the script isn't universal and as such might not be useful to everyone. But I'm glad someone else can find it useful.

afragen
05-11-2007, 01:56 AM
and assumes that there's a single network volume attached.!

This will/should work for multiple attached network AFP mounts. I'm sure something similar would work for any other mount type.

#!/usr/bin/env bash

sleep 45

if [[ `mount | awk '/^afp_/'` != "" ]]; then
num_mounts=`mount | grep -c ^afp`
for (( i = 0; i < $num_mounts; i++ )); do
afp=`mount | grep ^afp_ | awk {'print$3'} | sed -n '1p;1q'`
umount -f $afp
done
fi


Andy

chris_johnsen
05-11-2007, 05:12 AM
(The shell script code fragments below are untested since I don't have any AFP volumes, but people developing shell scripts might find the techniques useful.)

Here are some variations that I find a bit more natural for shell scripting:

mount | awk '/^afp_/ {print $3}' | xargs -n 1 umount -f

The -n 1 might not be needed on the xargs, but it results in the same umount invocations as the previous script (one per volume). Leaving the -n 1 off would put all the volumes into one umount invocation.

Of course, if you really want to always unmount all AFP volumes, something like this might work, too:

umount -Aft afp

That last variation is probably OK for AFP, but it is inappropriate for NFS since there are several NFS mediated mounts (automount) that are present on most systems (/Network, /Network/Servers, etc.). Changing afp to nfs in that last command would unmount these normal "volumes", too, which probably is not what the user really wants. Something like the first example with an extra pattern in the awk and/or an extra grep before the awk to select just the target volumes would probably be better for NFS volumes.

BTW, head -1 has the same result as sed -n '1p;1q', and is usually much easier to understand for those not versed in sed/ex/vi.

afragen
05-11-2007, 12:15 PM
Chris,

Thanks for the refinements and examples. I'm really just a shell scripting newbie. I love the ability to do so much with a small amount of code.

Though as I've just discovered all this code doesn't work if any of the mounts has a space in the name like "Macintosh HD". :-(

Andy

chris_johnsen
05-11-2007, 05:03 PM
(As before, I don't have any AFP volumes to test this with, but I did test the "space, single-quotes, and/or parentheses in the volume name" aspect with disk images.)

Though as I've just discovered all this code doesn't work if any of the mounts has a space in the name like "Macintosh HD". :-(

Andy

Yes, that's one of the problems with parsing the under-specified and largely undelimited output that the bare mount command produces (it is normally fine for human consumption, but not great for programs that want to do something with the data).

I worked up this hack to handle volume names with spaces (and single quotes, too):

mount | grep ^afp_ \
| sed -E -e 's/^.* on //;s/( \([^()]*\))?$//;'"s/'/'\\\\''/g;s/^/'/;s/\$/'/" \
| xargs umount -f


It could all be done in awk, but it looked ugly, so I reverted back to grep and sed. The idea is that the mount point probably directly follows " on " in the output from the mount command, and that the mount point name extends to the end of the line or to just before a space and a parenthesized string at the end of the line. By extracting the volume name using only what comes before and after it, we avoid getting tangled up with the spaces. There still some pitfalls:

if the volume name contains the string " on "
if the parenthesized expression that the OS adds contains parenthesis itself

If either of these come to pass, this code will fail to correctly extract the volume mount point. The first problem could be mostly alleviated if Perl-compatible regular expressions were available. The rest of the sed commands are difficult to read because of all the contortions required by the shell to get a couple of backslashes to sed. The end result is to put the entire line in single quotes (the last two commands), and escape any previously existing single quotes. This is done so that xargs will treat the volume name as one argument, whether it has spaces, single quotes, or anything else.

OK, here it is with Perl, to better handle the problem with " on " in volume names:
mount | grep ^afp_ \
| perl -pe 's/.*? on //;s/( \([^)]*\))?$//;'"s/'/'\\\\''/;s/^/'/;s/\$/'/" \
| xargs umount -f

The difference is the extra question mark before " on ". That modifies the star to do a non-greedy match. Don't expect all sed scripts to transfer that easily to Perl, but it was greatly influenced by sed, awk, and other tools, so I often jump into Perl when the job is just a bit too tough for grep, sed, awk, et al. That non-greedy match was the only thing I needed in this instance, though the functionality of the whole script (running mount, selecting and extracting the mount points, running umount) could be done in Perl if too many other tools also started falling short.

This Perl version still has the problem with parentheses in the parenthesized expression that follows the volume name. Is it safer to assume that users won't put parentheses in their volume names, or that Apple won't put them in the mount options list? If both are possible (and they definitely and probably are, respectively) then I don't see a clear way to distinguish between the volume name and the mount options (unless you assume the mount options will always have balanced parentheses, which can't be matched by regular expressions, so it would take a fancier approach anyway).

Oh, and both of these scripts still have a problem if the string " on " appears in the device part of the mount command's output. I haven't seen that happen, but I wouldn't rule it out (maybe AFP or NFS mounts already do that, I don't have anything to test with, but I'd guess AFP uses a URI-like device name and NFS uses the traditional machine:export device name). This is another intractable problem that stems from trying to parse the undelimited format of the output from the mount command. There has to be a better way to get at all this information (either through some delimited output, or an API: mount does it, Disk Utility does it, something else should be able to also), but it may be beyond what is reasonable in a simple little script.

afragen
05-11-2007, 07:18 PM
Chris,

Your hacks are beautiful. In some preliminary testing here with multiple AFP mounts, the perl version (the only one I'm testing), works great. Just so you know here's what some of my afp mount points look like from the mount command.

afp_003Js12XIRWg001Eic06SdO0-1.2d000054 on /Volumes/Backup (nodev, nosuid, mounted by afragen)
afp_003JrO1u5JvO001Eic06SdO0-1.2d000055 on /Volumes/AJF Photo (nodev, nosuid, mounted by afragen)

I was also trying to come up with a solution and think I've found another, less elegant way.

if [[ `mount | awk '/^afp_/'` != "" ]]; then
mount | awk '/^afp_/ {print $3}' | xargs -n 1 umount -f
num_mounts=`mount | grep -c ^afp`
for (( i = 0; i < $num_mounts; i++ )); do
mountpt=`mount | grep ^afp | grep -o '/.* (' | sed 's_/Volumes/__g' | sed 's_ (_:_g' | head -1`
cmd='tell application "Finder" to eject '\"$mountpt\"
osascript -e "$cmd"
sleep 2
done
fi


As I'm not nearly as adept I found that mixing in a little AppleScript to eject the Volumes with spaces works too. I too made the assumption about parens, but my assumption was that parens wouldn't be in a volume name and would be immediately after the mount point listed in the mount command. Probably not very good assumptions on the whole.

I really hope this gets indexed by Google as I've been trying to find a way to automatically unmount any connected drives when I switch locations on my laptop. BTW, I did figure that out. :) It involves a small shell script and a launchd process.

Of course, if there was some way to get the mount point from SD then we wouldn't have to go through all these contortions. But the exercise still helps me for the other script.

Andy

afragen
08-21-2007, 02:55 PM
Dave, could you post the contents of the 'mount' command when SMB shares are mounted? I'm trying to adapt my unmount script to handle afp, sshfs and smb shares. Unfortunately I don't have sshfs or smb shares to test with. TIA.

BTW, the script is always up at http://thefragens.com/pub/