0

I am trying to run 2 commands stored in a variable with osascript

This is my start.sh

currentDirectory="cd $(pwd) && npm run start"

echo $currentDirectory

osascript -e 'tell application "Terminal" to do script '"${currentDirectory}"''

I am getting this as the output

sh start.sh
cd /Users/Picadillo/Movies/my-test-tepo && npm run start
83:84: syntax error: Expected expression but found “&”. (-2741)
LuisEnMarroquin
  • 1,609
  • 1
  • 14
  • 26
  • I suggest to remove `cd $(pwd) &&` from your code. – Cyrus Aug 15 '22 at 19:55
  • @Cyrus I need that, I am starting that script from an MFE that needs other repo running – LuisEnMarroquin Aug 15 '22 at 19:57
  • It doesn't do anything. `$(pwd)` is the current directory, it's changing to where it already is. – Barmar Aug 15 '22 at 19:57
  • @Barmar Try running `cd Documents && osascript -e 'tell application "Terminal" to do script "ls"'` and you will see the `ls` output from the `~` directory – LuisEnMarroquin Aug 15 '22 at 19:59
  • 1
    Oh, I see. `$(pwd)` is being expanded in the context of the oroginal shell script, it's needed to get the AppleScript into the same directory. – Barmar Aug 15 '22 at 20:00

2 Answers2

2

@Barmar: The argument to do script needs to be in double quotes.

Yes; however, the way you’ve done it is still unsafe.

If the path itself contains backslashes or double quotes, AS will throw a syntax error as the munged AS code string fails to compile. (One might even construct a malicious file path to execute arbitrary AS.) While these are not characters that frequently appear in file paths, best safe than sorry. Quoting string literals correctly is always a nightmare; correctly quoting them all the way through shell and AppleScript quadratically so.

Fortunately, there is an easy way to do it:

currentDirectory="$(pwd)"

osascript - "${currentDirectory}" <<EOF 
on run {currentDirectory}
  tell application "Terminal"
    do script "cd " & (quoted form of currentDirectory) & " && npm run start"
  end tell
end run
EOF

Pass the currentDirectory path as an additional argument to osascript (the - separates any options flags from extra args) and osascript will pass the extra argument strings as parameters to the AppleScript’s run handler. To single-quote that AppleScript string to pass back to shell, simply get its quoted form property.

Bonus: scripts written this way are cleaner and easier to read too, so less chance of overlooking any quoting bugs you have in your shell code.

has
  • 161
  • 1
  • 1
  • 2
  • +⒈ This is the correct answer for anyone undecided, in case @LuisEnMarroquin doesn't return to update his choice. – CJK Aug 16 '22 at 23:18
1

The argument to do script needs to be in double quotes.

osascript -e 'tell application "Terminal" to do script "'"${currentDirectory}"'"'

You should also put the argument to cd in quotes, in case it contains spaces.

currentDirectory="cd '$(pwd)' && npm run start"
Barmar
  • 741,623
  • 53
  • 500
  • 612