User Tools

Site Tools


action:Execute_a_Shell_Script

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
action:Execute_a_Shell_Script [2019/04/25 05:11]
peternlewis UTF-8 and Non-ASCII Characters
action:Execute_a_Shell_Script [2019/05/03 23:54]
peternlewis [Quoting Strings]
Line 47: Line 47:
 ``` ```
  
-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:​Filter | Filter, Expand tilde (~) paths]] Action BEFORE the Execute Shell Script Action.+**Consider These Guidelines**
  
-For more info, see an excellent, detailed discussion of [[https://​forum.keyboardmaestro.com/​t/​png-metadata-comment/​6375/​29| How To Quote Paths by @ccstone]].+  * 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:​Filter | Filter, Expand tilde (~) paths]] Action BEFORE the Execute Shell Script 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. ​ So, for example, **this will _not_ work**: 
 + 
 +```bash 
 +# 🚫 Does NOT Work 
 +/​usr/​local/​bin/​emacsclient -e '​(w3m-browse-url "​$KMVAR_SafariURL"​)'​ 
 +``` 
 +because although the Variable is between double-quotes,​ it is in a string that is between single-quotes. 
 + 
 +  * So, to handle this case, you can use something like this: 
 + 
 +```bash 
 +# ✅ This WORKS 
 +/​usr/​local/​bin/​emacsclient -e '​(w3m-browse-url "'"​$KMVAR_SafariURL"'"​)'​ 
 +``` 
 +One key Bash feature that makes this work is that when two quoted strings are adjacent, they will be concatenated. ​ So after the Variable is expanded, the command string might look like this: 
 + 
 +```bash 
 +/​usr/​local/​bin/​emacsclient -e '​(w3m-browse-url "​https://​www.apple.com"​)'​ 
 +``` 
 + 
 +For more info, see these discussions in the Keyboard Maestro Forum: 
 +  * [[https://​forum.keyboardmaestro.com/​t/​png-metadata-comment/​6375/​29| How To Quote Paths by @ccstone]]. 
 +  * [[https://​forum.keyboardmaestro.com/​t/​trouble-expanding-variable-in-shell-script/​13664/​2?​u=jmichaeltx | Trouble Expanding Variable in Shell Script by @PeterNLewis]] 
 + 
 +---
  
 ==== UTF-8 and Non-ASCII Characters ==== ==== UTF-8 and Non-ASCII Characters ====
Line 86: Line 111:
 ===== Quoting Strings ===== ===== Quoting Strings =====
  
-Proper quoting of strings in a Shell Script is often a challenge.+Proper quoting of strings in a Shell Script is often a challenge. ​ In order to understand it, you have to understand what happens at each level of the processing. 
 + 
 +Thankfully, in an Execute Script action, Keyboard Maestro itself does not do any processing, so that is one less place for confusion. 
 + 
 +With shell commands, the important thing to understand is that, with only a few exceptional programs, it is not the command that does the processing, it is the shell (bash usually, although there are many shells). 
 + 
 +So for example with Keyboard Maestro variable set to `"​Selection Style" -int 0` and en Execute Shell Script command of: 
 + 
 +```bash 
 +defaults write /​Users/​me/​Library/​Application\ Support/​Witch/​Settings $KMVAR_witchPref 
 +``` 
 + 
 +It is the *bash* tool that sees the string and it processes it in to an array of strings which it passes to the *defaults* tool.  This is important - the defaults command receives not a single string, but an array of strings, in this case the array will be: 
 + 
 +* `defaults` 
 +* `write` 
 +*  `/​Users/​me/​Library/​Application Support/​Witch/​Settings` 
 +* `"​Selection` 
 +* `Style"​` 
 +* `-int` 
 +* `0` 
 + 
 +It is bash that has processed the variable substitution for $KMVAR_witchPref,​ split the line in to seven parts, processed the backslash in "​Application\ Support"​ and then executed the defaults tool with the seven parts as arguments (the command itself is the 0th argument, normally mostly ignored by tools). 
 + 
 +So the problem is that the word-breaking,​ variable substitution,​ de-quoting and de-backslash is all happening at as the line is processed by bash, after which you are left with quotes from within variable substitution,​ but they no longer have any meaning, they are just characters. 
 + 
 +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 instead, perhaps set one variable to the setting name, and one variable to the type and one variable to the value, and then use a command like this: 
 + 
 +```bash 
 +defaults write "/​Users/​me/​Library/​Application Support/​Witch/​Settings"​ "​$KMVAR_Setting"​ -"​$KMVAR_Type"​ "​$KMVAR_Value"​ 
 +``` 
 + 
 +Now a further complication happens when you want to sent a string containing double quotes and variables to a parameter. ​ For example, perhaps you want a command like this: 
 + 
 +```bash 
 +emacsclient -e '​(w3m-browse-url "​$KMVAR_SafariURL"​)'​ 
 +``` 
 + 
 +This will not work because bash only expands variables within double-quoted strings. ​ Within single quoted strings, they remain as the text `$KMVAR_SafariURL` (unchanged). ​ And so emactsclient will receive the array: 
 + 
 +* `emacsclient` 
 +* `-e` 
 +* `(w3m-browse-url "​$KMVAR_SafariURL"​)` 
 + 
 +But it will not expand the variable (that is the shell’s job). 
 + 
 +To work around this you need to use either all double quotes (and backslash any double quotes within them) such as: 
 + 
 +```bash 
 +emacsclient -e "​(w3m-browse-url \"​$KMVAR_SafariURL\"​)"​ 
 +``` 
 + 
 +or use a combination of strings, some double quoted and some single quoted: 
 + 
 +```bash 
 +emacsclient -e '​(w3m-browse-url "'"​$KMVAR_SafariURL"'"​)'​ 
 +``` 
 + 
 +Note that that parameter is now made up of three stings combined into one parameter: ​
  
-For a discussion on how to quote a string, see this [[https://​forum.keyboardmaestro.com/​t/​having-trouble-with-quotes-and-shell-variables/​6236/​9 | Keyboard Maestro Forum post by @PeterNLewis]].+* `(w3m-browse-url "​` ​single quoted string 
 +* the value of $KMVAR_SafariURL ​double quoted string 
 +* `"​)` ​single quoted string
  
  
action/Execute_a_Shell_Script.txt · Last modified: 2023/09/22 04:39 by peternlewis