MACROS: Mount Drive, Unmount Drive, Check if Drive is Mounted

MACROS: Mount Drive, Unmount Drive, Check if Drive is Mounted

External Drive Macros.v1.0.kmmacros (40.5 KB)

PURPOSE:

These 3 macros allow you to:

  1. Mount a drive (if it isn't already mounted).
  2. Unmount a drive (if it is mounted).
  3. Check to see if a drive is mounted.

NOTE:

If you want, instead of using these macros, you can just use the relevant actions, which I show along with the macros.


Mount Drive if Needed (Sub-Macro)

Relevant actions:

if ! [[ -d "/Volumes/$KMVAR_mdinDriveName" ]]; then
    diskutil quiet mount "$KMVAR_mdinDriveName"
fi

Unmount Drive if Needed (Sub-Macro)

Relevant actions:

if [[ -d "/Volumes/$KMVAR_udinDriveName" ]]; then
    diskutil quiet eject "$KMVAR_udinDriveName"
fi

Check if Drive is Mounted (Sub-Macro)

Relevant actions:

if  [[ -d "/Volumes/$KMVAR_cidmDriveName" ]]; then
    echo true;
else
    echo false;
fi
16 Likes

This is odd. It works perfectly for one of my drives, "Time Machine", but not for the other two, "AUDIO" and "Installers & Sessions". Could that be something to do with the former's capitalisation and the latter's inclusion of the "&" character?

Neil, can you share you final macros for this? I'm having a hard time understanding what to change and what to add...

This is what I ended up with:

Mount

Unmount

I tend not to use them though as I found that they sometimes wouldn't do anything. It might be particular to my system.

I do use Alfred's Eject All function though, which seems to work well.

So those are the main macros that then trigger the sub macros provided by @DanThomas?

I'm confused because of the instructions on the original macros:

USAGE:

Call this using an "Execute a Macro" action using "with parameter". In the Parameter field, pass the name of the drive, followed by "|", followed by the name of the variable to receive the result.

Example: "5TB Time Machine|isMounted" (without the quotes).

You don't seem to have that at all, the Execute a Macro and then the parameter thing...

I didn't use Dan's method in the end. I can't remember why. It might have been something to do with the script not liking the drive names.

Interesting that they all use diskutil.

I've found AppleScript to be quite reliable in mounting even network drives with passwords:

mount volume "smb://somenetworkdrive" as user name "myUserName" with password "myob"
3 Likes

Similarly

tell application "Finder" to eject disk "Disk Name"

...to eject.

...and I suppose you could make a pick-list of ejectable drives.

I made a start, but have a few issues:

You can make multiple selections in the list prompt, but I'm not sure how to do a "for each" in the AppleScript. I thought it might be along the lines of:

set inst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
	set toEject to getvariable "Local__Eject" instance inst
end tell

tell application "Finder"
	set theList to every disk whose ejectable is true
	repeat with eachItem in toEject
		eject eachItem
	end repeat
end tell

...but apparently AS can't "handle objects of this class". :man_shrugging:t2:

Also, the regex was removing both instances of lines containing "Macintosh HD", and now only one. :man_shrugging:t2::man_shrugging:t2:

Eject Disks.kmmacros (23 KB)

Macro screenshot

One issue would be that you can't pass an AS list object to a KM text-only variable then back to AS as a list object without doing some parsing.

I'd do it all in one AppleScript:

tell application "Finder"
	set ejectableList to name of every disk whose startup is false and (ejectable is true or local volume is false)
	tell application "System Events" to set theDisks to (choose from list ejectableList with title "Choose to Eject:" with multiple selections allowed without empty selection allowed)
	repeat with eachItem in theDisks
		eject disk eachItem
	end repeat
end tell

You can combine clauses in the whose filter, so we're telling it to make a list of the names of every ejectable local volume and any network volumes, but leave out the startup disk (saves you filtering the system disk, regardless of name).

I've popped the "Choose" dialog using System Events so it'll work even if the currently active app isn't scriptable.

If you prefer to use a KM list widget, try passing just the names (one per line) back to KM and returning text with one chosen disk name per line which you can loop through in AS with each paragraph.

What do you mean?

That looks nice and neat, but I tried it and it just runs indefinitely without anything visibly happening.

Do you know how to get a list of mountable drives and do the same thing in reverse? Presumably that would have to be a shell script, as Finder won't know about unmounted drives..?

Interesting -- runs fine here, ejecting both a mounted DMG and an USB stick at the same time. Files open on the disk, perhaps? Hidden processes like Spotlight can prevent a disk from ejecting, even in the Finder (which is where diskutil can win, and be more dangerous, with the force option).

I'm assuming you get the initial pick list!

I think that's going to depend on how you "removed" the disk in the first place. An AS eject makes the device ready for unplugging, so it's no longer visible to diskutil, whereas if you umount the volume it can be remounted by device number with eg diskutil mountDisk /dev/disk3.

So it's going to be a case of "what's your workflow, pick something that suits" (plus a "why are unmounting a physical volume without unplugging it anyway?" :wink: ).

No, nothing happens but the script is still running.

That's a very good point. :joy:

Try it while pushing the Finder to the front:

tell application "Finder"
    activate
	set ejectableList to name of every disk whose startup is false and (ejectable is true or local volume is false)
	set theDisks to (choose from list ejectableList with title "Choose to Eject:" with multiple selections allowed without empty selection allowed)
	repeat with eachItem in theDisks
		eject disk eachItem
	end repeat
end tell

To be fair, I can think of some use cases -- for example, mounting a backup disk while backups are running and unmounting it after, for some protection against a ransomware attack (more useful for daily backups than Time Machine). But it that case you don't unplug so the device number remains the same and you can remount directly, without having to create a list.

Ok that works. What's "home" doing there though?

CleanShot 2022-09-28 at 17.09.09@2x

I think it's some crazy Unix misdirection that wasn't thought of back in OS9!

"Not a local volume" is a very broad brush, so you'll probably want to narrow things down. So if you know you're going to be dealing with USB drives/sticks plus AFP and SMB network shares you could use:

set ejectableList to name of every disk whose startup is false and (ejectable is true or format is AppleShare format or format is SMB format)

Of course, if you know the names because you always use the same disks/volumes -- just use the names!

1 Like

That works perfectly!

That's great for me, but this should work for (pretty much) everyone.