how to pass bash variables to AppleScript - bash

#/bin/bash
corr="apple"
echo $corr
osascript -e 'tell application "Messages" to send "Did you mean "'"$corr"'" " to buddy "A"'
Error:
51:57: syntax error: A identifier can’t go after this “"”. (-2740)
If I just pass
osascript -e 'tell application "Messages" to send "Did you mean $corr " to buddy "A"'
the message comes like "Did you mean $corr"
I have tried everything mentioned at Pass in variable from shell script to applescript

There is a very good explanation with decent examples at the very end of here.
Based on that, I was able to make this work (using TextEdit, not Messages):
#!/bin/sh
rightNow=$(date +"%m_%d%B%Y")
osascript -e 'on run {rightNow}' -e 'tell application "TextEdit" to make new document with properties{name: "Date003.txt", text:rightNow}' -e 'end run' $rightNow
I also found that I had to be VERY careful about the single and double quotes. For some reason, my keyboard kept replacing the plain quotes with curled quotes. Annoying.

Related

Using bash for loops in conjunction with embedded applescript for bash scripts

I'm trying to get applescript to interact with the bash for loop that is a part of my code to keep from having to list each host manually and execute individual tell/end tell blocks for each host found in the hosts2.txt file.
The purpose of the script is to open a new terminal tab on my Mac and automatically launch "screen -r $HOST" in each new terminal until the end of the list of hosts in the hosts2.txt document. Each host is listed on its own line.
I've tried an all inclusive for loop, without the applescript "repeat 2 times" "end repeat" code that is shown below. It is repeating 2 times because there are only 2 hosts listed in the text document for testing purposes. Each time I have error output.
#!/bin/bash
for HOST in `cat ~/bin/hosts2.txt`
do echo $HOST
osascript -e 'repeat 2 times
tell application "Terminal" activate
tell application "System Events" to keystroke "t" using [command down]
tell application "Terminal" to activate
set host to $HOST
tell application "Terminal"
do shell script "screen -r " & host in front window
end tell
end repeat'
done
What I expect to happen is for the code the execute opening new terminal tabs with screen -r for each host. Error output is below this line.
dev
44:52: syntax error: Expected end of line but found command name. (-2741)
pulsar
44:52: syntax error: Expected end of line but found command name. (-2741)
There are a few issues with your script: some that stop it from working entirely; some that get it to do the wrong thing; and some that needn't have been there in the first place. There are couple of other answers that address some points, but neither of them appeared to test the script because there's a lot they don't address.
...for each host found in the hosts2.txt file...
...Each host is listed on its own line.
Then this line:
for HOST in `cat ~/bin/hosts2.txt`
is not what you want. That will create an array out of individual words, not lines in the file. You want to use the read command, that reads a file line-by-line. You can structure a loop in this manner:
while read -r HOST; do
.
.
.
done < ~/bin/hosts2.txt
As #entraz has already pointed out, your use of single quotes will stop shell variables from being expanding within your osascript.
Then there is the AppleScript itself.
I'm unclear why you included a repeat loop.
The purpose of the script is to open a new terminal tab on my Mac and automatically launch "screen -r $HOST" in each new terminal until the end of the list of hosts in the hosts2.txt document. Each host is listed on its own line.
It is repeating 2 times because there are only 2 hosts listed in the text document
This makes no sense, given that you implemented a bash loop in order to read the lines into the $HOST variable. Granted, you were reading words, not lines, but the AppleScript repeat is a head-scratcher. Bin it.
Then you have this:
tell application "Terminal" activate
tell application "System Events" to keystroke "t" using [command down]
tell application "Terminal" to activate
That's approximately infinity times the number you need to tell Terminal to activate.
This line:
set host to $HOST
will throw an error for two reasons: firstly, host is taken as an existing name of a property in AppleScript's standard additions, so you can't go and set it to a new value; secondly, there are no quotes around $HOST, so it's not going to be recognised as a string. But, this is just for your learning, as we're actually going to get rid of that line completely.
Finally:
tell application "Terminal"
do shell script "screen -r " & host in front window
end tell
is wrong. do shell script is not a Terminal command. It's a command belonging to AppleScript's standard additions. Therefore, if the rest of your code worked, and it got to this command, Terminal would execute nothing. Instead, the shell scripts would run in the background without an actual shell, so that's not much good to you.
The command you're after is do script.
Sadly, it does appear that, in High Sierra at least, the AppleScript commands to make new tabs and windows in Terminal no longer work, so I can see why you resorted to System Events to create a tab in the way that you have. Thankfully, that's not necessary, and nor are your multiple activate commands: do script will automatically run Terminal and execute a script in a new tab by default.
Therefore, the only AppleScript command you need is this:
tell application "Terminal" to do script "screen -r $HOST"
The Final Script
Putting this all together, here is the final hybrid script:
while read -r HOST; do
echo "$HOST"
osascript -e "tell application \"Terminal\" to do script \"screen -r $HOST\""
done < ~/bin/hosts2.txt
Alternatively
If you wanted to take the loop from bash and put it in AppleScript instead, you can do so like this, for which I'll use a heredoc (<<) to simplify the use of quotes and aid readability:
osascript <<OSA
property home : system attribute "HOME"
property file : POSIX file (home & "/bin/hosts2.txt")
set hosts to read my file using delimiter {return, linefeed}
repeat with host in hosts
tell application "Terminal" to do script ("screen -r " & host)
end repeat
OSA
You have a typo in your code.
The line tell application "Terminal" activate should be tell application "Terminal" to activate.
Variable expansion also doesn't work in single quotes in bash (single quotes means everything is interpreted literally), so the line set host to $HOST within the single quotes won't work.
Try this:
#!/bin/bash
for HOST in `cat ~/bin/hosts2.txt`
do echo $HOST
osascript -e "repeat 2 times
tell application \"Terminal\" to activate
tell application \"System Events\" to keystroke \"t\" using [command down]
tell application \"Terminal\" to activate
set host to \"$HOST\"
tell application \"Terminal\"
do shell script \"screen -r \" & host in front window
end tell
end repeat"
done
Edit: I think there's actually another problem: when setting a variable to a string in applescript, the string needs to be enclosed in quotes. So set host to $HOST causes an error because it interprets the value of $HOST ("pulsar" or "dev") as a command that it's unable to find/execute; it needs to be set host to \"$HOST\" instead. I've changed it above.
You might find a here-doc to be readable and easy to work with. Also, use a while-read loop to iterate over the lines of a file (ref: http://mywiki.wooledge.org/BashFAQ/001)
while read -r host; do
echo "$host"
osabody=$(cat << END_OSA
repeat 2 times
tell application "Terminal" to activate
tell application "System Events" to keystroke "t" using [command down]
tell application "Terminal" to activate
set host to "$host"
tell application "Terminal"
do shell script "screen -r " & host in front window
end tell
end repeat
END_OSA
)
osascript -e "$osabody"
done < ~/bin/hosts2.txt
The ending parenthesis of the $(cat ... command substitution has to be on a separate line because the terminating word of the heredoc must be the only characters on that line.

How to indent applescript when running in bash script?

osascript -e "set x to 3"
osascript -e "if x is 5 then"
osascript -e " tell application \"System Events\" to keystroke return"
osascript -e "end if"
The output i get
14:14: syntax error: Expected end of line but found end of script. (-2741)
0:6: syntax error: A “if” can’t go after this “end”. (-2740)
Can't see whats wrong with the script. Might be some issue with indentation. Anyone used osascript inside bash files ?
Put all your applescript lines together. This way:
osascript -e "set x to 3
if x is 5 then
tell application \"System Events\" to keystroke return
end if"
Additionally, you can create a file like the following with all your applescript code:
#!/usr/bin/osascript
set x to 3
if x is 5 then
tell application "System Events" to keystroke return
end if
I find this way easiest in respect of quoting and double-quoting and escaping, and using bash variables in the osascript:
#!/bin/bash
# Set bash variable to 3, then use it in osascript
count=3
osascript <<EOF
beep $count
tell application "Safari"
set theURL to URL of current tab of window 1
end tell
EOF
# Continue in bash
echo done

How to check auto proxy state for argument in shell script?

I don't have much experience with shell scripting and don't fully understand passing arguments to if else statements. I want to check the state of an auto proxy, i.e. whether it is enabled or disabled. if it is enabled(has an url) i want to turn it off and vice versa.
so far i have:
#!/bin/bash
if [[networksetup -getautoproxyurl "Wi-Fi"] = "https://mediahint.com/default.pac"] then
networksetup -setautoproxystate "Wi-Fi" off
osascript -e 'tell application "Terminal" to quit'
else
networksetup -setautoproxyurl "Wi-Fi" https://mediahint.com/default.pac
osascript -e 'tell application "Terminal" to quit'
fi
it's just the argument of the if statement i'm not sure on.
the statements work fine i have checked in another script.
Syntactically, all is ok, except the fiest line.
You must write:
if [ `networksetup -getautoproxyurl "Wi-Fi"` = "https://mediahint.com/default.pac" ]; then
Note:
backticks ``, that mean command subsitution;
; before then;
space before ] and after [.

How AppleScript can get STDIN inside the code?

Google suggests
echo "input" | osascript filename.scpt
with filename.scpt
set stdin to do shell script "cat"
display dialog stdin
However, I could get only blank dialog: it has no text. How can I get stdin from AppleScript at the version?
My OS version is OSX 10.8 Mountain Lion.
Sorry, not enough reputation to comment on answers, but I think there's something important worth pointing out here...
The solution in #regulus6633's answer is not the same as piping data into osascript. It's simply stuffing the entire pipe contents (in this case, echo output) into a variable and passing that to osascript as a commandline argument.
This solution may not work as expected depending on what's in your pipe (maybe your shell also plays a part?)... for example, if there are null (\0) characters in there:
$ var=$(echo -en 'ABC\0DEF')
Now you might think var contains the strings "ABC" and "DEF" delimited by a null character, but it doesn't. The null character is gone:
$ echo -n "$var" | wc -c
6
However, using #phs's answer (a true pipe), you get your zero:
$ echo -en 'ABC\0DEF' | osascript 3<&0 <<EOF
> on run argv
> return length of (do shell script "cat 0<&3")
> end run
>EOF
7
But that's just using zeros. Try passing some random binary data into osascript as a commandline argument:
$ var=$(head -c8 /dev/random)
$ osascript - "$var" <<EOF
> on run argv
> return length of (item 1 of argv)
> end run
>EOF
execution error: Can’t make some data into the expected type. (-1700)
Once again, #phs's answer will handle this fine:
$ head -c8 /dev/random | osascript 3<&0 <<EOF
> on run argv
> return length of (do shell script "cat 0<&3")
> end run
>EOF
8
According to this thread, as of 10.8 AppleScript now aggressively closes standard in. By sliding it out of the way to an unused file descriptor, it can be saved. Here's an example of doing that in bash.
Here we get at it again with a cat subprocess reading from the magic fd.
echo world | osascript 3<&0 <<'APPLESCRIPT'
on run argv
set stdin to do shell script "cat 0<&3"
return "hello, " & stdin
end run
APPLESCRIPT
Will give you:
hello, world
I know that "set stdin to do shell script "cat"" used to work. I can't get it to work in 10.8 though and I'm not sure when it stopped working. Anyway, you basically need to get the echo command output into a variable which can then be used as an argument in the osascript command. Your applescript needs to handle arguments too (on run argv). And finally, when you use osascript you must tell an application to "display dialog" otherwise it will error.
So with all that said here's a simple applescript which handles arguments. Make this the code of filename.scpt.
on run argv
repeat with i from 1 to count of argv
tell application "Finder"
activate
display dialog (item i of argv)
end tell
end repeat
end run
Here's the shell command to run...
var=$(echo "sending some text to an applescript"); osascript ~/Desktop/filename.scpt "$var"
I hope that helps. Good luck.
Late to this, but the original AppleScript seems to try to do something not allowed with osascript.
If in the original filename.scpt this line:
display dialog stdin
Is changed to:
tell application "System Events" to display dialog stdin
Then passing a value via stdin (as opposed to command line arguments) definitely still works in 10.7.5 Lion, maybe 10.8 Mountain Lion too.

How to print out the value of a variable in Applescript?

I have the following script:
i=1;
while [ $i -lt 51 ]
do
osascript -e 'tell app "Terminal"
do script "php $i.php"
end tell' &
i=$[$i+1]
done
I am trying to open a terminal window that executes 1 of 50 php scripts. However, I cannot get the value of $1 to print correctly. In fact, In each terminal its just blank. Each scripted is named 1.php to 50.php - how do I get the value of i to print properly to render the correct file name?
Note, I have been applescripting about an hour. Very open to suggestions to a better script. What I am trying to do is run 50 simultaneous PHP scripts in 50 separate windows simultaneously. Thanks!
It's just a quoting problem - change:
osascript -e 'tell app "Terminal"
do script "php $i.php"
end tell'
to:
osascript -e "tell app \"Terminal\"
do script \"php $i.php\"
end tell"

Resources