AppleScripts vs Shell Scripts

Why would you ever want to call a Shell Script in AppleScript when there is a native AppleScript method for getting the data? Shell Scripts are almost always much slower.

There is no native AppleScript method to get environment variables that contain non-ASCII characters.

system attributes does not work properly for environment variables that contain international characters.

do shell script "echo $KMVAR_My_KM_Variable" does.

as does

tell app "Keyboard Maestro Engine" to getvariable "My KM Variable"

It is far from clear which of the latter two would be faster. One involves interprocess communication via AppleEvents (which is extremely slow), and the other involves firing off a sub-process (which is extremely slow). Where by “extremely slow” I mean compared to reading an environment variable.

Without profiling all of them, I would have no idea which one would be fastest - but I do know which of the three wont work with international characters in the variable.

Peter, that does NOT work in AppleScript.

First, I run this macro to set and display the KM Variable:

MACRO:   Test Reading Emoji @Test

**Requires: KM 8.2.4+   macOS 10.11 (El Capitan)+**
(Macro was written & tested using KM 9.0+ on macOS 10.14.5 (Mojave))

#### DOWNLOAD Macro File:
<a class="attachment" href="/uploads/default/original/3X/a/c/acce29d77386eb7ff93e853fa48b89f7d8a821cc.kmmacros">Test Reading Emoji @Test.kmmacros</a>
**Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.**


---


<img src="/uploads/default/original/3X/2/4/2429ff14a20a68bae4ed828d8819aaac6ab4d895.png" width="490" height="513">

---

### Example Results
![image|316x264](upload://msqPcDrYOxeriwzP6NuCi9jjnBb.png) 

`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

And then run this AppleScript 

![image|690x148](upload://lyMflFdwDVMASeEjziWfSUTM0HN.png) 

```applescript
set emojiSS to do shell script "echo $KMVAR_TEST__emoji"

return emojiSS
```

However, when I run this AppleScript 
```applescript
tell application "Keyboard Maestro Engine" to set emojiStr to getvariable "TEST__emoji"
```

it works fine:

![image|690x191](upload://61g7MLg9galwqvFWQO2VwsYVDER.png) 

Oh, and BTW, I think you grossly overstated the facts with:

[quote="peternlewis, post:6, topic:16174"]
One involves interprocess communication via AppleEvents (which is extremely slow), and the other involves firing off a sub-process (==which is extremely slow==).
[/quote]

since it ran in << 0.01 seconds.

So, I would again recommend to all AppleScript users:

[quote="JMichaelTX, post:5, topic:16174"]
Why would you ever want to call a Shell Script in AppleScript when there is a native AppleScript method for getting the data? Shell Scripts are almost always much slower.
[/quote]

Sometimes a shell script is the only solution.  But if you have another choice, use it.

Of course it does. It's been tested and used for years.

image

Environment variables are not global, you can't run the AppleScript in a seperate process (I presume that is Script Debugger?) and access environment variables.

This technique works only from within an AppleScript executed from Keyboard Maestro - it is an alternative to the broken system attribute.

If you want to access Keyboard Maestro variables from another process, then there is no other way than accessing them via AppleScript.

Quote the whole paragraph:

Here is some quick testing I did:

  • Shell do nothing loop: 2.8µs/loop
  • Shell read international environment variable: 3.6µs/loop
  • AppleScript do nothing loop: 0.2µs/loop (impressive)
  • AppleScript read international environment variable via broken system attribute: 80µs/loop
  • AppleScript read international environment variable via AppleEvents: 620µs/loop
  • AppleScript read international environment variable via do shell script: 2700µs/loop

Clearly, all of them are “fast enough” if you aren't doing a lot of them. But also clearly, AppleEvents and sub processes are “extremely slow” compared to reading environment variables directly.

If you are doing a lot of variable access from AppleScript, and you know the variable is restricted to ASCII characters, then system attribute will be approximately ten times faster than getvariable, and alternatively, doing it all within a shell script may be wise if you need a lot of variable accesses that may contain international characters.

image

1 Like

All that really matters here is that native AppleScript (even using AppleEvents to tell "Keyboard Maestro Engine") is 4X FASTER than using shell script.

I still object to your use of the pejorative, relative, term "extremely slow" -- which really means nothing, but can convey to some users a process requiring many seconds, when in fact the process is only 0.00062 seconds. I think most users, certainly myself, would consider that "very fast".

Running this script:

tell application "Keyboard Maestro Engine" to set emojiStr to getvariable "TEST__emoji"
return emojiStr

in the timing tool Script Geek (written by AppleScript guru Shane Stanley) provides an average (over 100 runs) of:
0.002 seconds

Running this script:

set emojiSS to do shell script "echo $KMVAR_TEST__emoji"

return emojiSS

requires 0.006 seconds in Script Geek.

So, I rest my case that it is ALWAYS faster and better to use AppleScript native commands, even tell application commands, than it is to use shell scripts.

BTW, using KM shell script to run an AppleScript via osascript is the worst way to run an AppleScript. It is much slower than running the same AppleScript via Script Debugger 7, Script Editor, or FastScripts.

Results

image

So, AppleScript run by

  • Script Geek: 0.002 seconds
  • KM Execute AppleScript: 0.16 seconds

==KM is 80X SLOWER.==

MACRO:   Test 2 Reading Emoji @Test copy

**Requires: KM 8.2.4+&nbsp;&nbsp;&nbsp;macOS 10.11 (El Capitan)+**
(Macro was written & tested using KM 9.0+ on macOS 10.14.5 (Mojave))

#### DOWNLOAD Macro File:
<a class="attachment" href="/uploads/default/original/3X/8/d/8da4d67fbbff12fdcfdbe0ba898e7519c35da07f.kmmacros">Test 2 Reading Emoji @Test copy.kmmacros</a>
**Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.**


---


<img src="/uploads/default/original/3X/b/c/bcf141b39832ac4806f2a4b670b34241857571a9.png" width="630" height="781">

I have moved our discussion of using AppleScripts vs Shell Scripts to a new topic.