i wrote a working handler to eject images and disks and external drives.
Unfortunately the last step (jump to #eject volume) isn’t always working, sometimes a disk (partition) wants not to be unmounted, because : “in use”
whats missing, please?
eject_all()
on eject_all()
tell application "System Events"
set bl_ls to {name of startup disk, "home", "net"}
set all_images to name of disks whose ejectable is true
end tell
#eject images --system events shows mounted images, istead of disks
repeat with a in all_images
do shell script "hdiutil unmount " & "'/Volumes/" & a & "'; sleep 0.3"
end repeat
#eject partitions
tell application "Finder"
try #finder throws an error if no disks are available
set get_partitions to name of disks whose ejectable is true #whose owner is not "System"
on error
set get_partitions to {}
end try
end tell
if get_partitions is not {} then
repeat with a in get_partitions
if a is not in bl_ls then do shell script "hdiutil unmount '/Volumes/" & a & "'; sleep 0.3"
end repeat
end if
#eject volume
set all_disks to paragraphs of (do shell script "diskutil list | grep /dev/")
repeat with a in all_disks
if a does not end with "disk0" then
try
do shell script "hdiutil detach" & a
on error
do shell script "sleep 0.3"
try
do shell script "hdiutil detach -force " & a
end try
end try
end if
end repeat
end eject_all
There are two kinds of volumes, ejectable (disk images, shared volumes, flash drives) or
mountable (internal or external hard disks)
¢ Ejectable volumes are unmounted and then removed from the IOReg database
If a physical device contains more than 1 partition, the whole disk is ejected even passing a single mounting point
¢ Mountable volumes are only unmounted
I recommend to use hdiutil for the images and diskutil for the other volumes
If a hard disk is busy, the volume is forced to be unmounted.
The sleep statements are not needed. The shell returns the result after having completed the task
set theResult to {}
tell application "System Events"
set all_images to POSIX path of disks whose ejectable is true -- everything which can be ejected
set all_disks to disks whose ejectable is false and POSIX path starts with "/Volumes" -- everthing which can be unmounted filtering {"/", "/home", "/net"}
end tell
repeat with anImage in all_images
try -- will throw an error after a device with multiple partitions has been ejected and the second mount point is passed
set end of theResult to do shell script "hdiutil eject -force " & quoted form of anImage
end try
end repeat
repeat with aDisk in all_disks
tell application "System Events" to tell (contents of aDisk) to set {mountPoint, isBusy} to {its POSIX path, busy status}
if isBusy then
set end of theResult to do shell script "diskutil unmount force " & quoted form of mountPoint
else
set end of theResult to do shell script "diskutil unmount " & quoted form of mountPoint
end if
end repeat
set {TID, text item delimiters} to {text item delimiters, return}
set theResult to theResult as text
set text item delimiters to TID
display dialog theResult