Call an AppleScript with a parameter, receive a return code from the AppleScript

I know this is probably very simple, and I've looked at others' examples of doing similar, but not exactly the same thing. I'd appreciate a gentle, non-judgmental pointer in the right direction. I am aware of AppleScript and have used a few scripts written by others over the years, but I've never set up my own.

I am trying to do the following:

Set a variable to a string representing the name of a disk drive in KM
Pass that drive name to AppleScript with that disk name as the parameter

Execute a simple AppleScript like this:
tell application "Finder"
activate
eject (passed disk name)
end tell

If possible, I'd like the AppleScript to return a code indicating success or failure of eject command. If that's not possible I suppose I could just use KM to see if the drive is still mounted, but I'd still like to know how to return a value from the AppleScript to KM.

And that's it. I've spent far too much time failing at getting this to work correctly.

Also, I've seen people use "local_" as part of the names of variables, but I haven't looked into local vs. global vars in KM yet. If someone could point me to the right place in the Wiki for that, I'd appreciate it.

Please understand I'm asking for some fishing education, not just a fish! If there's a clear explanation I haven't been able to find, that'd be great also!

The AppleScript section of the wiki explains how you can do this with variables. As a rough untested example, something like this:

set kmInst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
	set myDiskName to getvariable "local_theDiskName" instance kmInst
end tell

tell application "Finder"
	activate
	eject disk myDiskName
end tell

That would eject the disk—I think :). I'm no AppleScript expert, though. To use it, you'd use Set Variable in your macro to set the variable local_theDiskName to the name of the disk to eject. (Note: I'm not sure about quoting of spaces in AppleScript variable values, you might have to do something that I'm not familiar with.)

As for global vs instance vs local, many of us (myself included) use local as the default, and instance and global only when strictly required. A local variable exists only for the duration of the macro that created it. An instance variable can exist in the macro that created it, and any other macros that macro calls, but also vanishes when the macro that created it ends. A global variable is permanent, and can be used anywhere.

Much more detail on the scope of variables here:

https://wiki.keyboardmaestro.com/manual/Variables

-rob.

As for confirming the disk has been ejected, I think you'd have to wrap the tell application Finder section in a try/end try pair, with an on error error handler. That section could set a return variable you could check in Keyboard Maestro:

try
...
...
on error
	tell application "Keyboard Maestro Engine"
		setvariable "local_Error" instance kmInst to "Error"
	end tell
end try

But I will admit I am not the right person to write this macro—an AppleScript expert will respond with a much better solution, I am sure :). But those are the right two sections of the wiki to study.

If I were doing this myself, I'd use shell commands, not AppleScript. diskutil list lists all drives, diskutil unmount /dev/disk1s2 unmounts the specified drive. You could then verify it's been ejected by running diskutil list again, and searching the results to make sure your drive is no longer listed. I would go this route because I suck at AppleScript, but can write passable shell scripts :).

-rob.

Thanks for the suggestions. Perhaps I wasn't clear. I'm not trying to learn how to eject a disk - I'm trying to learn how to pass values between KBM and an AppleScript, for the rare occasions where there is some task AppleScript can do that KBM can't. I have no desire to learn AppleScript in-depth. I picked a simple example that I've been struggling with as a "proof of concept".

I do appreciate your reply, and I will check out the references you provided.

The examples I provided both pass a value to, and return a value from, AppleScript. I thought that was exactly what you wanted to see. In particular...

Passing a value in:

set kmInst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
	set myDiskName to getvariable "local_theDiskName" instance kmInst
end tell

Getting a value out, assuming you have the set kmInst... bit set earlier:

	tell application "Keyboard Maestro Engine"
		setvariable "local_Error" instance kmInst to "Error"
	end tell

-rob.

2 Likes

@griffman's shown you how to explicitly pass values between particular KM and AS variables. There's also the "Save results to a variable" option in KM's "Execute an AppleScript" action. AS will return the result of the last thing it does when executing the script:

...and you can explicitly return a certain value:

...or multiple values, which you can then parse in KM:

...although that can get tricky as everything is coerced to text so you have to careful of delimiters appearing within the data itself -- better, for anything complicated, to use the methods Rob showed.

You could also use the system clipboard (in both directions) or even read/write data from/to a text file, either within AS or by using the action's output options -- and probably other ways I've not remembered.

So many options!

3 Likes