Bash expand variable inside osascript command - bash

Can someone tell me how to make the variable expand in the following, please:
MESSAGE="Public IP Address has changed"
osascript -e 'tell application (path to frontmost application as text) to display \
dialog "My message is ${MESSAGE} " buttons {"OK"} with icon stop'

The single quotes are preventing variable expansion: 3.1.2.2 Single Quotes
MESSAGE="Public IP Address has changed"
osascript -e 'tell application (path to frontmost application as text) to display \
dialog "My message is '"$MESSAGE"' " buttons {"OK"} with icon stop'
# ....................^^........^^
I'm using shell string concatenation there:
a single quote to close the first part of the single quoted string,
the variable expanded within double quotes,
a single quote to open the last part of the single quoted string.

Related

Run 2 commands in applescript/osascript with variable

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)
#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.
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"

Can't pass variable with spaces in name through a bash osascript shell script

I'm writing a script to pass a complete file path with spaces in the name to a remote computer over ssh, which needs to run using iTerm. It needs to happen through AppleScript embedded into a shell script so I can take control of iTerm, create new split views, etc.
I've simplified my script here purely to the section that isn't working. For demonstration purposes, and so people here might be able to try alternatives, I've changed the command in question to the 'cd' command, as the error is the same (it can't find the path due to spaces in it).
#!/bin/bash
PATH="$1"
ssh server#192.168.50.4 "osascript \
-e 'tell application \"iTerm\"' \
-e 'activate' \
-e 'set newWindow to (create window with default profile)' \
-e 'tell first session of current tab of current window' \
-e 'write text \"cd "$PATH"\"' \
-e 'end tell' \
-e 'end tell'"
This works fine if there's no spaces in the path. The remote machine opens up an iTerm window and the path is changed to cd path. However, if there's spaces in the name, such as…
Volumes/Work/My Folder With Spaces
…iTerm responds with -bash: cd: Volumes/Work/My: No such file or directory
I've tried using $# and putting extra quotes around the $1 variable and/or the $PATH variable. Also, I know there's an AppleScript command that's something like "quoted form of (POSIX path)" but I have no idea how to integrate it here within the bash script.
I just figured it out! the script I was writing was an After Effects render script. Turns out it became a lot simpler if I used EOF instead of starting each line with -e. It solved all the issues I was having with nested quotes, etc.
#!/bin/bash
ssh server#192.168.50.4 osascript <<EOF
tell application "iTerm"
activate
set newWindow to (create window with default profile)
select first window
tell current session of current window
end tell
tell first session of current tab of current window
write text "/Applications/Adobe\\\\ After\\\\ Effects\\\\ 2020/aerender -project \"$1\" -sound ON"
end tell
end tell
EOF

Terminal Applescript unable to escape quote

I've run into a strange problem when trying to include quote marks ' ' in my osascript command.
If I try and escape a normal escapable character, it works fine. Example: osascript -e 'tell app "Finder" to display dialog "Te\\st"' A dialog box from Finder pops up with the text Test in it.
However, the problem occurs when I try and use apostrophes when I'm writing out full sentences. Example: osascript -e 'tell app "Finder" to display dialog "Te\'st"' When I run this, all I'm left with is no dialog box, and the text input in terminal looking like this:
>
From what I know, this should by all means work, however, it doesn't.
Just to complement #Zero's helpful answer (which indeed does solve the problem):
Since you're using osascript, it is the shell's (bash's) quoting rules that apply first:
In bash (or any POSIX-compatible shell), you cannot include single quotes in a single-quoted string - not even with escaping.
What you CAN do, however, is to break your string into multiple pieces and simply splice in single quotes where needed (escaped outside a quoted string as \'):
osascript -e 'tell app "Finder" to display dialog "Te'\''st"'
'tell app "Finder" to display dialog "Te', the first part, is followed by the escaped single quote \', followed by the remainder of the string 'st"'
By virtue of having NO spaces between the parts, bash creates a single string that does contain the spliced-in literal '.
It is generally easier to pass single-quoted strings to osascript, since double quotes are frequently used in AppleScript and therefore have to be escaped when enclosed in a double-quoted string (as in the accepted answer).
In the typically infrequent event that you must pass a single quote to AppleScript, you can use the technique described in this answer.
You can do it this way:
osascript -e "tell app \"Finder\" to display dialog \"'Something' in quotes"\"

Trouble escaping quotes in a shell script

I have a bash script I am making that generates some numbers assignes them to variables then uses osascript to write them out in any application of choice.
Here is a simplified version of what I want to do.
monday1=5
osascript -e 'tell application "System Events" to keystroke "$monday1"'; \
The osascript should look like this
osascript -e 'tell application "System Events" to keystroke "5"'; \
This will then type out the number 5 in what ever app I have my cursor in. The problem is it outputs $monday1 instead. I know I have to do something to escape the quotes so the script can input the variable, but I'm not sure how.
Thoughts?
The problem is that inside single quotes, there are no special metacharacters, so $monday1 is passed to osascript unchanged. So, you have to make sure that $monday1 is not inside single quotes.
Your options include:
monday1=5
osascript -e 'tell application "System Events" to keystroke "'$monday1'"'
monday1=5
osascript -e 'tell application "System Events" to keystroke "'"$monday1"'"'
monday1=5
osascript -e "tell application \"System Events\" to keystroke \"$monday1\""
monday1=5
osascript -e "tell application 'System Events' to keystroke '$monday1'"
The first stops the single-quoting just after the double quote to surround the key stroke, embeds the value of $monday, and resumes the single-quoting for the remaining double quote. This works because there are no spaces etc in $monday1.
The second is similar to the first but surrounds "$monday1" in double quotes, so it will work even if $monday1 contained spaces.
The third surrounds the whole argument with double quotes, and escapes each embedded double quote. If you're not allergic to backslashes, this is good.
The fourth may or may not work — it depends on whether the osascript program is sensitive to the type of the quotes surrounding its arguments. It simply reverses the use of double quotes and single quotes. (This works as far as the shell is concerned. Gordon Davisson observes in a comment that osascript requires double quotes and does not accept single quotes, so it doesn't work because of the rules of the invoked program — osascript.)
In both the third and fourth cases, you need to be careful if there are other parts of the string that need to be protected so that the shell does not expand the information. In general, single quotes are better, so I'd use one of the first two options.
The single quotes form a scope without variable substitution.
osascript -e "tell application \"System Events\" to keystroke \"$monday1\""; \
Wrapping your entire string in single quotes prevents the variable monday1 from being interpolated. Switch your double and single quotes:
osascript -e "tell application 'System Events' to keystroke '$monday1'";

How to change directory with spaces in applescript terminal?

I'm new to applescripts and I'm trying to automate a process, but how do you change directory through the script when there are spaces inside the directory? My commands should be correct but a syntax error keeps popping up:
Expected “"” but found unknown token.
Here is my script:
tell application "Terminal"
activate
do script "cd ~/Pictures/iPhoto\ Library"
end tell
I don't understand where it is wrong. It works fine on my terminal.
Thanks a bunch guys!!
UPDATE: this worked best!!
# surround in single quotes
tell application "Terminal"
activate
do script "cd '/Users/username/Pictures/iPhoto Library'"
end tell
The are a few ways.
# escape the quotes with a backslash. AND Escape the first backslash for Applescript to accept it.
tell application "Terminal"
activate
do script "cd ~/Pictures/iPhoto\\ Library"
end tell
# surround in double quotes and escape the quotes with a backslash.
tell application "Terminal"
activate
do script "cd \"/Users/username/Pictures/iPhoto Library\""
end tell
# surround in single quotes using quoted form of
tell application "Terminal"
activate
do script "cd " & quoted form of "/Users/username/Pictures/iPhoto Library"
end tell
# surround in single quotes
tell application "Terminal"
activate
do script "cd '/Users/username/Pictures/iPhoto Library'"
end tell
Also I do not thing the tild will expand when you use the quotes on the whole path.
So you will need to get the user name another way.
Examples:
# inserting the user name. And surrond in brackets so the name and path are seen as one string before the quotes are added
set whoami to do shell script "/usr/bin/whoami"
tell application "Terminal"
activate
do script "cd /Users/" & quoted form of whoami & "/Pictures/iPhoto\\ Library"
end tell
tell application "System Events" to set whoami to name of current user
# inserting the user name. And surrond in brackets so the name and path are seen as one string before the quotes are added
tell application "Terminal"
activate
do script "cd /Users/" & quoted form of (whoami & "/Pictures/iPhoto Library")
end tell
As you can see there is more than one way to do any of this.
Or just quote the directory part.
Example.
tell application "Terminal"
activate
do script "cd ~" & quoted form of "/Pictures/iPhoto Library"
end tell

Resources