#3
|
|||
|
|||
Revised code
Here is a revised version of my code to selectively mount and unmount volumes, and call SD! scripts unattended. I've sorted out various issues, and it now works fine as a cron job; I rely on it nightly.
Overall, the code has been improved by never telling anything to the Finder. 'unmount' now only unmounts the given volume, without ejecting other volumes on the same disk. It is possible to have an AppleScript such as this that calls 'diskutil' crash on rare occasions. I don't know why, and I'm not sure that I'm actually doing anything wrong. (SD! itself sometimes uses 'disktool' instead of 'diskutil', despite Apple's efforts to wean us from it; perhaps Dave can explain why?) Also on rare occasions, I'd run a prior version of this script unattended, and one of the volumes failed to unmount. I considered what I would have done manually had I been there, and wrote a wrapper 'unmountVol' to do exactly that. It looks like massive overkill in the calm light of day, but its precautions are entirely harmless for unattended operations. I leave diagnostic journaling on at all times, as SD! does. If anything odd happens, this is invaluable. Note that all shell script commands are logged, together with any errors returned, even for commands that always return an error. (We wouldn't want to miss it, if one of them returned a different error.) All forums have a high percentage of lurkers. I google and lurk various places to pick up code fragments to try, and I consider this to be the primary value of posting code on the web; I don't like to use unsupported code that I haven't rewritten myself. To be conservative, if no one else has posted here that this code worked for them, proceed with caution in modifying it for your needs. This is an AppleScript library file, Backups Library.scpt. Opening it opens the script in the Script Editor: Code:
property logfile : "/Volumes/User/Users/ad/Scripts/logs/log" -- initialized, journal, shell, wait : utility routines property new : true on initialize() if new then set logfile to logfile & (do shell script "date '+ %Y-%m-%d.txt'") set new to false end if end initialize on journal(message) local wasnew, s, f set wasnew to new if new then initialize() set s to (quoted form of message) set f to ">>" & (quoted form of logfile) & "; " if wasnew then do shell script "echo " & f & "echo " & s & f & "echo " & f else do shell script "echo `date '+%H:%M:%S'` ' ' " & s & f end if end journal on shell(command) -- use full paths for any commands not in path "/usr/bin:/bin" local e, n journal(" % " & command) try do shell script command on error e number n journal(" ! " & (n as string) & " " & e) error e number n end try end shell on wait(interval) shell("sleep " & interval as string) end wait -- ismounted, mount, unmount : mounting and unmounting volumes on ismounted(volname) try -- if not found, egrep exits with a non-zero status shell("/sbin/mount | egrep 'on /Volumes/" & volname & " \\(.+\\)$'") on error journal(" - " & volname) return false end try journal(" + " & volname) return true end ismounted on mount(volname) local a journal("mount: " & volname) if not ismounted(volname) then try -- if not found, grep and egrep exit with a non-zero status set a to shell("/usr/sbin/diskutil list | egrep '^ +[[:digit:]]+: +[[:graph:]]+ +" & volname & " +[.[:digit:]]+ GB +disk[[:alnum:]]+$'") set a to shell("echo '" & a & "' | sed 's/" & volname & "//' | awk '{print $5}'") shell("/usr/sbin/diskutil mount " & a & " | grep '^Volume " & a & " mounted$'") on error return false end try end if return true end mount on unmount(volname) local n journal("unmount: " & volname) if ismounted(volname) then try -- unmount always generates error "Volume failed to unmount", even when successful shell("/usr/sbin/diskutil unmount '/Volumes/" & volname & "'") end try end if end unmount -- mountVol, unmountVol : patient, stubborn wrappers for mount, unmount on mountVol(pause, tries, volname) local n journal("mountVol " & volname) repeat with n from 1 to tries wait(pause) if mount(volname) then repeat with n from 2 to 8 wait(n) if ismounted(volname) then return true end repeat end if end repeat return false end mountVol on unmountVol(pause, tries, volname) local n journal("unmountVol " & volname) repeat with n from 1 to tries wait(pause) unmount(volname) repeat with n from 2 to 8 wait(n) if not ismounted(volname) then return true end repeat end repeat return false end unmountVol -- mountVolumes, unmountVolumes : apply mountVol, unmountVol to lists on mountVolumes(pause, tries, volnames) local status journal("mountVolumes") set status to true repeat with volname in volnames if not mountVol(pause, tries, volname) then set status to false end repeat return status end mountVolumes on unmountVolumes(pause, tries, volnames) local status journal("unmountVolumes") set status to true repeat with volname in volnames if not unmountVol(pause, tries, volname) then set status to false end repeat return status end unmountVolumes -- SuperDuper! on SuperDuperJob(volname, scriptalias) local wasmounted journal(scriptalias as string) journal("") set wasmounted to ismounted(volname) if wasmounted or mountVol(30, 4, volname) then journal("SuperDuperJob: " & scriptalias as string) try run script scriptalias on error e number n journal("script error: " & (n as string) & " " & e) end try if not wasmounted then unmountVol(30, 4, volname) end if journal("") end SuperDuperJob -- top level routines on mountBackups() mountVolumes(0, 1, {¬ "aOSX", "aOS9", "aOSX 10.4.4 min", "aOSX 10.3.9 min", "aUser", ¬ "bOSX", "bOS9", "bOSX 10.4.4 min", "bOSX 10.3.9 min", "bUser", ¬ "FireWire A OSX", "FireWire A"}) end mountBackups on unmountBackups() unmountVolumes(0, 1, {¬ "aOSX", "aOS9", "aOSX 10.4.4 min", "aOSX 10.3.9 min", "aUser", ¬ "bOSX", "bOS9", "bOSX 10.4.4 min", "bOSX 10.3.9 min", "bUser", ¬ "FireWire A OSX", "FireWire A"}) end unmountBackups on runBackups() journal("runBackups") SuperDuperJob("aOS9", ¬ alias "User:Users:ad:Scripts:Smart Update aOS9 from OS9.sdsp:Copy Job.app:") SuperDuperJob("aOSX 10.3.9 min", ¬ alias "User:Users:ad:Scripts:Smart Update aOSX 10.3.9 min from OSX 10.3.9 min.sdsp:Copy Job.app:") SuperDuperJob("aOSX 10.4.4 min", ¬ alias "User:Users:ad:Scripts:Smart Update aOSX 10.4.4 min from OSX 10.4.4 min.sdsp:Copy Job.app:") SuperDuperJob("aUser", ¬ alias "User:Users:ad:Scripts:Smart Update aUser from User.sdsp:Copy Job.app:") SuperDuperJob("aOSX", ¬ alias "User:Users:ad:Scripts:Smart Update aOSX from OSX.sdsp:Copy Job.app:") SuperDuperJob("aBack", ¬ alias "User:Users:ad:Scripts:Smart Update Sources image from User.sdsp:Copy Job.app:") SuperDuperJob("aBack", ¬ alias "User:Users:ad:Scripts:Smart Update Users image from User.sdsp:Copy Job.app:") end runBackups Code:
set BackupsLib to (load script file "User:Users:ad:Scripts:Backups Library.scpt") tell BackupsLib runBackups() end tell Code:
unmountVol aBack 07:11:37 % sleep 0 07:11:37 unmount: aBack 07:11:37 % /sbin/mount | egrep 'on /Volumes/aBack \(.+\)$' 07:11:37 + aBack 07:11:37 % /usr/sbin/diskutil unmount '/Volumes/aBack' 07:12:04 ! 1 Volume failed to unmount 07:12:05 % sleep 2 07:12:07 % /sbin/mount | egrep 'on /Volumes/aBack \(.+\)$' 07:12:07 ! 1 The command exited with a non-zero status. 07:12:07 - aBack |
Currently Active Users Viewing This Thread: 2 (0 members and 2 guests) | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Problems automating backups with applescript and crontab | kbradnam | General | 4 | 01-20-2006 07:40 AM |
Strongspace SuperDuper backup strategy options? | parakeet | General | 1 | 12-21-2005 09:16 PM |
Backup and archive strategy and method? | xoshooter | General | 3 | 10-07-2005 04:28 PM |
applescript help | snoopy67 | General | 1 | 09-17-2005 09:07 AM |
AppleScript bug? fixed! | pzingg | General | 1 | 11-02-2004 06:37 PM |