Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

BATman.Berlin

macrumors regular
Original poster
Jun 13, 2015
239
183
California
I have a few drives connected to my dock. Often I just unplug ad get a lot of annoying notifications. Is there a way to either disable them or run a macro that automatically un-mounts all drives?

Thanks
 
Yesterday I wrote small app exactly for that purpose.
It can eject USB connected as well as network volumes and also lists them separately in a menu from where they can be accessed. It purposefully ignores SD-Cards. It can be customised at will as it's AppleScript based.
Bildschirm­foto 2023-02-21 um 16.10.59.png

 

Attachments

  • Unmounter.zip
    66.2 KB · Views: 83
  • Like
Reactions: bogdanw
Yesterday I wrote small app exactly for that purpose.
It can eject USB connected as well as network volumes and also lists them separately in a menu from where they can be accessed. It purposefully ignores SD-Cards. It can be customised at will as it's AppleScript based.
Rather than sharing the app, consider sharing the code and how to save it as an app.
https://support.apple.com/en-us/guide/script-editor/scpedt1072/2.11/mac/11.0
Inexperienced users will be welcomed by the “unidentified developer” message when trying to open the app.
 
Rather than sharing the app, consider sharing the code and how to save it as an app.
[…]
So here you are:
To generate an application from the script (it can't be run as a script) follow these simple steps.
  1. Download the script and unpack it (if not done automatically).
  2. Open the script with Apple Script editor (preinstalled with the OS).
    Screenshot 2023-02-23 at 18.12.23.png
  3. Select Duplicate from the File menu.

  4. Save the script as an Application with the following settings enabled.
    Screenshot 2023-02-23 at 18.06.30.png
 

Attachments

  • Unmounter.zip
    12.2 KB · Views: 82
Last edited:
Your code:
AppleScript:
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property StatusItem : missing value
property selectedMenu : "" -- each menu action will set this to a number, this will determin which IP is shown
property theDisplay : ""
property defaults : class "NSUserDefaults"
property internalMenuItem : class "NSMenuItem"
property externalMenuItem : class "NSMenuItem"
property newMenu : class "NSMenu"
property theList : "Populating…"

if not (current application's NSThread's isMainThread()) as boolean then
    display alert "This script must be run from the main thread." buttons {"Cancel"} as critical
    error number -128
end if

on menuNeedsUpdate:(menu)
    my makeMenus()
end menuNeedsUpdate:

on makeMenus()
    newMenu's removeAllItems() -- remove existing menu items
    set exceptionsList to (do shell script "system_profiler SPCardReaderDataType | grep Mount | cut -c37-") ## & (do shell script "ls Volumes | grep ^Backups")
    set inclusionList to do shell script "find /Volumes -maxdepth 1 -not -user root | cut -c 10-" as string
    try
        set networkShares to do shell script "mount | grep -E 'afpfs|smbfs|nfs' | sed -e 's/.* on \\(.*\\) (.*/\\1/' | cut -c10- | grep -v '\\.'" ## mount | grep -E 'afpfs|smbfs|nfs' | sed -e 's/.* on \(.*\) (.*/\1/' | cut -c10- | grep -v '\.'
    end try
    
    tell application "Finder"
        set diskList to the disks whose ejectable is true and local volume is true and format is not unknown format
        set mounts to {}
        repeat with mountedDisk in diskList
            if name of mountedDisk is not in exceptionsList and name of mountedDisk is in inclusionList then
                try
                    set ejectingDisk to do shell script "echo " & mountedDisk & " | sed 's/.$//'" ##| grep -v :[A-Z,a-z]"
                    set the end of mounts to ejectingDisk
                end try
            end if
        end repeat
        try
            set shareList to the disks ##whose ejectable is true
            set shares to {}
            repeat with mountedShare in shareList
                if name of mountedShare is in networkShares then
                    try
                        set currentShare to do shell script "echo " & mountedShare & " | sed 's/.$//' | grep -v :"
                        set the end of shares to currentShare
                    end try
                end if
            end repeat
        end try
    end tell
    
    if mounts is {} and shares is {} then
        set volumes to "no external volumes to eject"
    else
        set volumes to {""}
    end if
    set someListInstances to {"Eject USB storage", "Eject network shares", ""} & mounts & volumes & shares & {"", "Quit"}
    repeat with i from 1 to number of items in someListInstances
        set this_item to item i of someListInstances
        if this_item is "" then
            (newMenu's addItem:(current application's NSMenuItem's separatorItem))
        else if this_item is "Quit" then
            set thisMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:this_item action:"someAction:" keyEquivalent:"q")
            (newMenu's addItem:thisMenuItem)
            (thisMenuItem's setTarget:me) -- required for enabling the menu item
        else if this_item is "Eject USB storage" then
            set thisMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:this_item action:"someAction:" keyEquivalent:"e")
            (newMenu's addItem:thisMenuItem)
            (thisMenuItem's setTarget:me) -- required for enabling the menu item
        else if this_item is "Eject network shares" then
            set thisMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:this_item action:"someAction:" keyEquivalent:"k")
            (newMenu's addItem:thisMenuItem)
            (thisMenuItem's setTarget:me) -- required for enabling the menu item
        else
            set thisMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:this_item action:"someAction:" keyEquivalent:"")
            (newMenu's addItem:thisMenuItem)
            (thisMenuItem's setTarget:me) -- required for enabling the menu item
        end if
    end repeat
end makeMenus

on someAction:sender
    set aTag to tag of sender as integer
    set aTitle to title of sender as string
    set exceptionsList to (do shell script "system_profiler SPCardReaderDataType | grep Mount | cut -c37-")
    ## & (do shell script "ls Volumes | grep ^Backups")
    set inclusionList to do shell script "find /Volumes -maxdepth 1 -not -user root | cut -c 10-" as string
    try
        set networkShares to do shell script "mount | grep -E 'afpfs|smbfs|nfs' | sed -e 's/.* on \\(.*\\) (.*/\\1/' | cut -c10- | grep -v '\\.'"
    end try
    
    if aTitle is equal to "Quit" then
        quit
    else if aTitle is equal to "Eject USB storage" then
        tell application "Finder"
            set diskList to the disks whose ejectable is true
            repeat with mountedDisk in diskList
                if name of mountedDisk is not in exceptionsList and name of mountedDisk is in inclusionList then
                    set ejectingDisk to do shell script "echo " & mountedDisk & " | sed 's/.$//'"
                    eject mountedDisk
                    
                    display notification ("\"" & ejectingDisk & "\" ejected")
                end if
            end repeat
        end tell
    else if aTitle is equal to "Eject network shares" then
        try
            do shell script "find /Volumes -maxdepth 1 -not -user root -print0 | xargs -0 umount -t smbfs,nfs,afpfs"
            ##        on error errorMessage
            ##            display alert "An error occured" message "Not all network shares could be ejected…
            
            ##" & errorMessage
        end try
        display notification (networkShares & " ejected")
    else if aTitle is "no external volumes to eject " then
        do shell script "open /Volumes"
    else
        do shell script "open \"/Volumes/" & aTitle & "\""
    end if
end someAction:

-- create an NSStatusBar
on makeStatusBar()
    set bar to current application's NSStatusBar's systemStatusBar
    set StatusItem to bar's statusItemWithLength:-1.0
    StatusItem's setTitle:"💾"
    set newMenu to current application's NSMenu's alloc()'s initWithTitle:"Custom"
    newMenu's setDelegate:me
    StatusItem's setMenu:newMenu
end makeStatusBar

my makeStatusBar()
that can be copy-pasted into Script Editor.
 
None of the apps resolves the issue of just unplugging the hub without ejecting the disks first. The unmount must happen before the OP yanks the plug from the computer and - more or less - must be done manually. Unmount first, unplug later.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.