action:Execute_a_Shell_Script
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| action:Execute_a_Shell_Script [2021/09/18 20:32] – [Using Keyboard Maestro Variables] ccstone | action:Execute_a_Shell_Script [2025/09/12 07:02] (current) – [Quoting Strings] peternlewis | ||
|---|---|---|---|
| Line 7: | Line 7: | ||
| * It is best to always specify the language using the `#!` at the front of the script. | * It is best to always specify the language using the `#!` at the front of the script. | ||
| * The script is executed with the `sh` shell, so if you want to use another language, or use any special kinds of shell-specific syntax, then you should specify the language. | * The script is executed with the `sh` shell, so if you want to use another language, or use any special kinds of shell-specific syntax, then you should specify the language. | ||
| + | * The shell is a non-login shell, so configuration files (like .bashrc) will not be run - in particular, this means you will not have much in the PATH (see [[# | ||
| * For more details and examples, see [[https:// | * For more details and examples, see [[https:// | ||
| Line 17: | Line 18: | ||
| If the script fails, the action will fail (v9.0+), potentially aborting the macro. | If the script fails, the action will fail (v9.0+), potentially aborting the macro. | ||
| + | Keyboard Maestro sets the environment variables for the script to include all your variables, using a prefix of `KMVAR_` and your variable name with spaces changed in to underscores (‗). For example, your Keyboard Maestro “File Name” variable will be available as the environment variable `KMVAR_File_Name`. | ||
| + | Keyboard Maestro also provides (v10.0+) a number of environment variables that contain information about the executing macro. These include: | ||
| + | |||
| + | ^environment variable^meaning^ | ||
| + | |`KMINFO_MacroName`|The name of the parent executing macro| | ||
| + | |`KMINFO_MacroUUID`|The UUID of the parent executing macro| | ||
| + | |`KMINFO_MacroGroupName`|The name of the macro group containing the parent executing macro| | ||
| + | |`KMINFO_MacroGroupUUID`|The UUID of the macro group containing the parent executing macro| | ||
| + | |`KMINFO_ThisMacroName`|The name of the executing macro| | ||
| + | |`KMINFO_ThisMacroUUID`|The UUID of the executing macro| | ||
| + | |`KMINFO_ThisMacroGroupName`|The name of the macro group containing the executing macro| | ||
| + | |`KMINFO_ThisMacroGroupUUID`|The UUID of the macro group containing the executing macro| | ||
| + | |`KMINFO_TriggerTime`|The [[/ | ||
| + | |`KMINFO_TriggerBase`|The type of the trigger that started the parent macro| | ||
| + | |`KMINFO_Trigger`|The trigger description of the trigger that started the parent macro| | ||
| + | |`KMINFO_TriggerValue`|the value associated with how the parent macro was triggered| | ||
| + | |`KMINFO_ActionResult`|The success or failure of the immediate past action| | ||
| + | |`KMINFO_LastWindowID`|The window ID of the most recently displayed Keyboard Maestro Engine window| | ||
| + | |`KMINFO_PromptWithListText`|The text typed in the most recently executed [[action: | ||
| + | |`KMINFO_PasteByNameText`|The text typed in the most recently executed [[action: | ||
| ==== Using Keyboard Maestro Variables ==== | ==== Using Keyboard Maestro Variables ==== | ||
| - | === Most Languages like bash, perl, ruby === | + | Keyboard Maestro variables are included in the environment of the script, with the prefix `KMVAR_` and spaces in the name replaced with underscores (‗), |
| - | In your script, use this format: | + | By default, all variables are included, but you can select No Variables, or specific variables as desired using the popup menu next to the script (v11.0+). |
| - | where // | + | === Most Shell Languages like bash === |
| - | For example: | + | In your script, use this format $KMVAR‗*VARIABLE‗NAME* where *VARIABLE‗NAME* is the name of your Keyboard Maestro Variable, but with spaces in the name replaced with underscores (‗). |
| + | |||
| + | For example: | ||
| If your variable already has underscores, | If your variable already has underscores, | ||
| Line 33: | Line 56: | ||
| {{: | {{: | ||
| - | Keep in mind that `$KMVAR_[variable_name]` | + | Keep in mind that $KMVAR‗*VARIABLE‗NAME* |
| - | * This is format is directly accessible | + | Note that you can only read these environment variables. |
| - | * But other languages will probably require | + | |
| - | * Perl for instance requires: `my $var = $ENV{KMVAR_VarName}; | + | |
| - | ==== Python | + | ==== Perl==== |
| - | Accessing Keyboard Maestro Variables in Python is somewhat different. | + | ```perl |
| + | my $fileName = $ENV{KMVAR_File_Name}; | ||
| + | ``` | ||
| - | REQUIRES: The following two Keyboard Maestro variables to exist and contain the requisite text: | + | ==== Python ==== |
| - | + | ||
| - | local_DataStr | + | |
| - | local_CharToCount | + | |
| ```python | ```python | ||
| # | # | ||
| - | # Python Version: 2.7.x | ||
| import os | import os | ||
| - | print os.environ[' | + | print os.environ[' |
| ``` | ``` | ||
| See the [[# | See the [[# | ||
| - | |||
| - | Note that you can only read these environment variables. | ||
| ==== awk ==== | ==== awk ==== | ||
| Line 67: | Line 84: | ||
| ```bash | ```bash | ||
| - | # EXAMPLE 1 – Using an awk variable in an awk script: | + | awk -v awkVariable=" |
| - | + | ||
| - | awk -v myVar=4 'BEGIN {print "myVar is " myVar}' | + | |
| - | + | ||
| - | # --> My var is 4 | + | |
| - | + | ||
| - | # --------------------------------------------------------------------------------------- | + | |
| - | + | ||
| - | # EXAMPLE 2 – Printing a shell variable with awk: | + | |
| - | + | ||
| - | myShellVariable=' | + | |
| - | + | ||
| - | awk -v awkVariable=" | + | |
| - | + | ||
| - | # --> The value of VAR is: What can I do for you today? | + | |
| - | + | ||
| - | # --------------------------------------------------------------------------------------- | + | |
| - | + | ||
| - | # EXAMPLE 3 – Using KM Variables with awk | + | |
| - | + | ||
| - | (You must have a value in the Keyboard Maestro variable My_KM_Variable.) | + | |
| - | + | ||
| - | awk -v awkVariable=" | + | |
| - | + | ||
| - | # --> The value of My_KM_Variable is: " | + | |
| ``` | ``` | ||
| - | |||
| - | For a KM Macro that shows this, see:\\ | ||
| - | **[MACRO: | ||
| - | |||
| ==== Passing Paths in Variables ==== | ==== Passing Paths in Variables ==== | ||
| If you are passing a file/folder path in a Keyboard Maestro Variable, then it is best to put the Variable reference in double quotes so that spaces in the path will work, like this: | If you are passing a file/folder path in a Keyboard Maestro Variable, then it is best to put the Variable reference in double quotes so that spaces in the path will work, like this: | ||
| + | |||
| ```bash | ```bash | ||
| cat " | cat " | ||
| Line 106: | Line 96: | ||
| **Consider These Guidelines** | **Consider These Guidelines** | ||
| - | * This must be a full path. **If the path starts with a tilde (~)**, then you must first convert it to a full path using the [[action: | + | * This must be a full path. **If the path starts with a tilde (~)**, then you must first convert it to a full path using the [[action: |
| * Like all Bash variables, the Keyboard Maestro Variable must _not_ be between single quotes (`'`) in order for the variable to be expanded to / replaced by its value. | * Like all Bash variables, the Keyboard Maestro Variable must _not_ be between single quotes (`'`) in order for the variable to be expanded to / replaced by its value. | ||
| ```bash | ```bash | ||
| # 🚫 Does NOT Work | # 🚫 Does NOT Work | ||
| - | / | + | echo 'The variable is "$KMVAR_File_Name"' |
| ``` | ``` | ||
| + | |||
| because although the Variable is between double-quotes, | because although the Variable is between double-quotes, | ||
| Line 119: | Line 110: | ||
| ```bash | ```bash | ||
| # ✅ This WORKS | # ✅ This WORKS | ||
| - | / | + | echo 'The variable is "'" |
| ``` | ``` | ||
| + | |||
| One key Bash feature that makes this work is that when two quoted strings are adjacent, they will be concatenated. | One key Bash feature that makes this work is that when two quoted strings are adjacent, they will be concatenated. | ||
| ```bash | ```bash | ||
| - | / | + | echo 'The variable is "Test.txt"' |
| ``` | ``` | ||
| - | |||
| - | For more info, see these discussions in the Keyboard Maestro Forum: | ||
| - | * [[https:// | ||
| - | * [[https:// | ||
| ==== UTF-8 and Non-ASCII Characters ==== | ==== UTF-8 and Non-ASCII Characters ==== | ||
| Line 143: | Line 131: | ||
| * Trim Results — removes white space from the start and end of the scripts results. | * Trim Results — removes white space from the start and end of the scripts results. | ||
| * Include Errors — include stdout and stderr results from the script. | * Include Errors — include stdout and stderr results from the script. | ||
| - | |||
| ==== Output of Results ==== | ==== Output of Results ==== | ||
| Line 149: | Line 136: | ||
| The results of a shell script can be: | The results of a shell script can be: | ||
| - | * Ignored. | + | {{page> |
| - | * Displayed in a floating window. | + | |
| - | * Displayed briefly in a Notification. | + | If the output is going to a clipboard or a file, the downloaded data can be an image (v11.0+). |
| - | * Displayed large across | + | |
| - | * Typed in to the current selection. | + | If you want to return multiple values from a script, then you can use AppleScript (via `osascript`) to [[manual: |
| - | * Pasted in to the current selection. | + | |
| - | * Saved to a variable. | + | |
| - | * Appended to a variable | + | |
| - | * Saved to the system or a Named Clipboard. | + | |
| - | * Asynchronously ignored — the action runs while the macro continues on. | + | |
| - | If you want to return multiple values from a script, then you can either use AppleScript (via `osascript`) to [[manual: | ||
| ===== Examples ===== | ===== Examples ===== | ||
| Line 193: | Line 174: | ||
| It is bash that has processed the variable substitution for $KMVAR_witchPref, | It is bash that has processed the variable substitution for $KMVAR_witchPref, | ||
| - | So the problem is that the word-breaking, | + | So the problem is that the word-breaking, |
| So variables that are meant to be a single parameter should be surrounded by double quotes in the line, but not contain quotes in the variable, and generally you do not want to pass multiple parameters within a single parameter. | So variables that are meant to be a single parameter should be surrounded by double quotes in the line, but not contain quotes in the variable, and generally you do not want to pass multiple parameters within a single parameter. | ||
| Line 201: | Line 182: | ||
| ``` | ``` | ||
| - | Now a further complication happens when you want to sent a string containing double quotes and variables to a parameter. | + | Now a further complication happens when you want to send a string containing double quotes and variables to a parameter. |
| ```bash | ```bash | ||
| Line 240: | Line 221: | ||
| The tr command will replace `\r` or `\n` line endings with a nul character, and the `xargs -0` command will read that, split the arguments at the nul character, and pass them to the specified command (in this case `ls -l`. Note that xargs has a limit to the number of arguments it will pass, so for large numbers of arguments it may run the command multiple times with subsets of the arguments - read the `xargs` man page for more details. | The tr command will replace `\r` or `\n` line endings with a nul character, and the `xargs -0` command will read that, split the arguments at the nul character, and pass them to the specified command (in this case `ls -l`. Note that xargs has a limit to the number of arguments it will pass, so for large numbers of arguments it may run the command multiple times with subsets of the arguments - read the `xargs` man page for more details. | ||
| + | |||
| + | Also note that shell globing happens after variable expansion, and so if the variable contains `*` characters they will be expanded by the shell by matching file names in the current directory. To avoid this, you can turn off globing by using the -f option when executing bash - that is, start your script with `# | ||
| ===== Path in Shell Scripts ===== | ===== Path in Shell Scripts ===== | ||
| - | **In essence, the _default_ path in a Keyboard Maestro Execute Shell Script is the base path for the system:** | + | In essence, the _default_ path in a Keyboard Maestro Execute Shell Script is the base path for the system: |
| / | / | ||
| - | that is the script will search for tools in the `/usr/bin` directory, then in the `/bin` directory, then `/usr/sbin` and finally `/ | + | That is the script will search for tools in the `/usr/bin` directory, then in the `/bin` directory, then `/usr/sbin` and finally `/ |
| - | * **shell | + | * Shell scripts are executed in non-interactive mode (see the INVOCATION section of the sh man page), the **only** path preset by default is the system path. |
| - | | + | * Thus, your tools or files may not be automatically accessible. |
| * The `$PATH` environment variable you may have set in Terminal is **not** used. | * The `$PATH` environment variable you may have set in Terminal is **not** used. | ||
| - | * None of your profile scripts (like *~/.profile*) will be executed. | + | * None of your profile scripts (like `~/.profile`) will be executed. |
| * Custom environment variable settings will not be applied, including any settings for tool-specific environment variables like PERL5LIB. | * Custom environment variable settings will not be applied, including any settings for tool-specific environment variables like PERL5LIB. | ||
| - | **How To Set a Path** | + | Generally, the best thing to do is to use full paths when referring to tools, such as `/ |
| - | | + | |
| - | | + | If you need access to tools (executables) or files that you installed (not part of the system installation), |
| - | | + | * Use an explicit, full path to the tool or file. See [[# |
| - | | + | |
| - | * The path defined in this Variable | + | * Set `ENV_PATH` Keyboard Maestro |
| - | * You can set this Variable manually in the [[manual: | + | |
| - | * Once the `ENV_PATH` Variable is set, it will remain in your Keyboard Maestro Variable set (until/ | + | Any Keyboard Maestro variable that starts with `ENV_` |
| - | * If your tool requires other environment variables to be set you can set them as well by creating an appropriate | + | |
| - | * For example, if you want to use [[https:// | + | |
| - | **Setting | + | You can set this Variable manually in the [[manual: |
| - | A shell script path that will work for many users is: | + | If your tool requires other environment variables to be set you can set them as well by creating an appropriate Keyboard Maestro variable with `ENV_` at the front. |
| - | / | + | For example, if you want to use [[https://www.perl.org/ | Perl]] with a custom library search path in the Execute a Shell Script action, you can also create a Keyboard Maestro variable `ENV_PERL5LIB` that will set the [[http://perldoc.perl.org/perlrun.html# |
| - | Of course, | + | (!) Note that if in the action |
| - | You can create the `ENV_PATH` Variable one time using the [[manual: | + | ===== Working Directory ===== |
| - | * Add a variable named `ENV_PATH` and set its value. | + | |
| - | * Once set, it will remain unchanged until you change or delete it. | + | |
| - | {{: | + | The working directory for any executed scripts will be set from the Keyboard Maestro `ENV_PWD` directory (v10.0+), or default to the root directory (`/`). |
| - | For a good discussion about this see: | ||
| - | * [KM can"t find shell commands ](https:// | ||
| - | * [[https:// | ||
| ===== Execute Script From Other Apps ===== | ===== Execute Script From Other Apps ===== | ||
| - | When you execute a shell script from other apps, like Terminal.app, | + | When you execute a shell script from other apps, like Terminal.app, |
| In order to access Keyboard Maestro Variables in these scripts, you must use a tool like [[https:// | In order to access Keyboard Maestro Variables in these scripts, you must use a tool like [[https:// | ||
| - | (!) Note that you do NOT need to replace spaces with underscores in your Variable name in this case, since you are ultimately using AppleScript in the Shell Script. | + | Here is a simple example to **get** a variable: |
| - | + | ||
| - | Here is a simple example | + | |
| < | < | ||
| - | osascript -e 'tell application " | + | osascript -e 'tell application " |
| </ | </ | ||
| - | If you are using Keyboard Maestro 7.1+ you can use the new simpler command to **get** a variable: | + | (!) Note that you do **not** replace spaces with underscores in your variable |
| - | < | + | |
| - | osascript -e 'tell application " | + | |
| - | </ | + | |
| - | To **set** a variable (and create if needed) | + | To **set** a variable (and create if needed) you can use this: |
| < | < | ||
| osascript -e 'tell application " | osascript -e 'tell application " | ||
| Line 330: | Line 301: | ||
| === Actions === | === Actions === | ||
| + | * [[action: | ||
| * [[action: | * [[action: | ||
| * [[action: | * [[action: | ||
| Line 357: | Line 329: | ||
| - [[https:// | - [[https:// | ||
| - [[https:// | - [[https:// | ||
| + | For more info, see these discussions in the Keyboard Maestro Forum: | ||
| + | - [[https:// | ||
| + | - [[https:// | ||
| + | - [[https:// | ||
| + | - [[https:// | ||
| - [[https:// | - [[https:// | ||
| **Keywords: | **Keywords: | ||
action/Execute_a_Shell_Script.1631997161.txt.gz · Last modified: by ccstone
