11

I've got a shell script that I call that uses osascript, and that osascript calls a shell script and passes in a variable that I've set in the original shell script. I don't know how to pass that variable in from the applescript to shell script.

How can I pass in a variable from shell script to applescript to shell script...?

Let me know if I don't make sense.

 i=0
 for line in $(system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p' -e '/iPhone/,/Serial/p' | grep "Serial Number:" | awk -F ": " '{print $2}'); do
 UDID=${line}
 echo $UDID
 #i=$(($i+1))
 sleep 1


 osascript -e 'tell application "Terminal" to activate' \
 -e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down' \
 -e 'tell application "Terminal" to do script "cd '$current_dir'" in selected tab of the front window' \
 -e 'tell application "Terminal" to do script "./script.sh ip_address '${#UDID}' &" in selected tab of the front window'

 done
SirRupertIII
  • 12,324
  • 20
  • 72
  • 121

2 Answers2

15

Shell variables don't expand inside single quotes. When you to want pass a shell variable to osascript you need to use double "" quotes. The problem is, than you must escape double quotes needed inside the osascript, like:

the script

say "Hello" using "Alex"

you need escape quotes

text="Hello"
osascript -e "say \"$text\" using \"Alex\""

This not very readable, therefore it much better to use the bash's heredoc feature, like

text="Hello world"
osascript <<EOF
say "$text" using "Alex"
EOF

And you can write multiline script inside for a free, it is much better than using multiple -e args...

ccpizza
  • 28,968
  • 18
  • 162
  • 169
clt60
  • 62,119
  • 17
  • 107
  • 194
  • This is bad advice. Aside from being unnecessarily clumsy, it does not sanitize the inserted text so is neither robust nor secure, e.g. `text='Bob says "hello"'` will cause AS to throw a syntax error due to unescaped quotes. Never use code munging if a better solution exists, which it does: as Lauri Ranta said, define an explicit `run` handler and pass your strings via ARGV. See http://stackoverflow.com/questions/16966117/bash-combining-variables-to-form-a-command-sent-to-applescript-using-the-osascr/16977401#16977401 for more detail. – foo Jun 22 '13 at 09:14
  • 1
    @foo You're right, using `on run argv` is "more" correct. Mine is not an _perfect_ solution, but i'm used it myself many-many times without any problems, it is simple and usable for many scripts... – clt60 Jun 22 '13 at 10:22
  • 1
    Yours is a _buggy_ solution. If $text contains double quote or backslash characters it will cause the AS code either to error or - worse - behave in unintended ways. If you must use code munging, you _must_ sanitize your inputs. e.g. Google "SQL injection attack" to understand why "it works for me" is _not_ an appropriate response when someone points out this flaw. – foo Jun 23 '13 at 08:11
2

You can also use a run handler or export:

osascript -e 'on run argv
    item 1 of argv
end run' aa

osascript -e 'on run argv
    item 1 of argv
end run' -- -aa

osascript - -aa <<'END' 2> /dev/null
on run {a}
    a
end run
END

export v=1
osascript -e 'system attribute "v"'

I don't know any way to get STDIN. on run {input, arguments} only works in Automator.

Lri
  • 26,768
  • 8
  • 84
  • 82