KM Shell Script: How to set $PATH and change directory

I am trying to figure out how to source the path for a shell script macro and then pass in a new directory location where I want the script to execute. Also, is it possible to get the macro to execute in the terminal?

SETTING THE PATH: I tried using the command "source ~/.zshrc" and "source ~/.bash_profile" in different versions of the macro, but Keyboard Maestro is adding its default path information (/usr/bin:/bin:/usr/sbin:/sbin) to selected elements I'm seeing in .zshrc and .bash_profile path results. Unfortunately, it's not finding "usr/local/bin" which shows up in both of the source commands in the terminal. So, I'm not sure how Keyboard Maestro is building the path. Do you have any tricks?

CHANGING DIRECTORY: Since Keyboard Maestro starts the macro in the root, I need a way to pass it a directory before the rest of the script executes. How are you doing this? I've read somewhere that you can set a variable outside the script in Keyboard Maestro that passes in a value. Is that what you all do? Are there other ways?

EXECUTING IN TERMINAL: Is there a way to get the macro to call a terminal session and send the output to stdout?

You can do so using Trigger by Shell Script, and execute them in command line .

You can add path to ENV_PATH as documented at https://wiki.keyboardmaestro.com/action/Execute_a_Shell_Script

1 Like

Hello and welcome! I hope you find this a helpful and friendly place to get help with Keyboard Maestro! Responses below...

The best way to set the path is using the ENV_PATH using the link that macdevign_mac shared.

Note that Keyboard Maestro uses bash for its shell unless you tell it to use something else.

99% of the time I have Keyboard Maestro call an external script file, but if I am using a script inside Keyboard Maestro I have a Typinator shortcut that starts a zsh template for me:

#!/usr/bin/env zsh -f

if [[ -e "$HOME/.path" ]]
then
	source "$HOME/.path"
fi

# Add stuff here

exit 0

because I always want to be using zsh not bash.

This really depends on what you are trying to do. If you are trying to take action on a selected file or files in Finder, for example, then I send the full path to the script. If I need to be in a certain directory when I take the action, I just use cd

You can set variables in Keyboard Maestro's preferences if they are things you need to have available for every script (like ENV_PATH). You can also have a Keyboard Maestro macro set the result of actions to variables, or clipboards to variables, or just text to variables.

When trying to access those variables from a shell script, the most important thing to know is that you must add the prefix $KMVAR_ to the variable name. So, for example, if you have a variable in Keyboard Maestro called BREAKFAST then to use it in a shell script you would refer to it as `$KMVAR_BREAKFAST.

(You might deduce that I have not yet eaten this morning. You would be correct.)

Yes, you can call any Keyboard Maestro macro using AppleScript, and you can call AppleScripts via shell scripts or in terminal.

For example, here's one of my macros and where to find the correct code for calling it via shell script. If you click on "Or by Shell script" it will show you the proper syntax for a variety of options:

Generally, calling the macro by the UUID is recommended unless you are absolutely sure that you will never rename the macro.

1 Like

Thanks for the tips about passing in the PATH and starting directory via Keyboard Maestro variables. This works well, and since I want to share this macro with my colleagues, I assume that they can insert their own variable values for $ENV_PATH and their own script directory.

Still, I found two issues with the two approaches I tried (calling an external script and passing in the commands inside script text). These both worked but here's the problem:

  • The stdout isn't available until the script exits, so users can't see the status of the script steps.
  • The final line in the script starts a Node server and doesn't exit because it is actively running the server. This, of course, means that the user never knows that the script completed successfully, unless they open the local website that is served up by Node. This isn't ideal.

So, it sounds like if I want to use Keyboard Maestro to run and display the script output in Terminal.app, I need to use AppleScript. This seems like a lot of extra work when I could just run the shell script from the terminal. I'm in a Git environment so, I maybe I could just create an alias to find and execute the script that lives outside my Git-controlled directory.

You need to set the shell script to run asynchronously, and within the script action save the last process (which is node process) to a file which you can then check if the process still running. In this mode the action will not block

In this way, you can proceed to run both run the server, and then subsequently running Custom HTML Prompt Action which load a HTML file. Essentially this give a quick alternative to Electron , especially for utility type of application.
The HTML has javascript which in turn to call macro to quit its node process.

Some sophisticated application can be built using this approach (eg I built Personal Inventory application using the mentioned way)