Combining variables in Bash to form a command sent to AppleScript using the osascript command

随声附和 提交于 2019-11-26 20:43:34

问题


I'm trying to make this script work. It's a Bash script that is meant to take some variables, put them together and use the result to send an AppleScript command. Manually pasting the string echoed from the variable to_osa behind osascript -e to the terminal works as I want and expect it to. But when I try to combine the command osascript -e and the string to_osa, it does not work. How can I make this work?

the_url="\"http://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash\""
the_script='tell application "Safari" to set the URL of the front document to '
delimiter="'"
to_osa=${delimiter}${the_script}${the_url}${delimiter}
echo ${to_osa}
osascript -e ${to_osa}

In addition to working manually the script also works when I write the desired command to a script and then execute it:

echo "osascript -e" $to_osa > ~/Desktop/outputfile.sh
sh  ~/Desktop/outputfile.sh

回答1:


As a general rule, don't put double-quotes in the variable, put them around the variable. In this case it's more complicated, since you have some double-quotes for bash-level quoting, and some for AppleScript-level quoting; in this case, the AppleScript-level quotes go in the variable, the bash-level quotes go around the variable:

the_url="\"http://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash\""
the_script='tell application "Safari" to set the URL of the front document to '
osascript -e "${the_script}${the_url}"

BTW, using echo to check things like this is highly misleading. echo is telling you what's in the variable, not what'll be executed when you reference the variable on a command line. The biggest difference is that echo prints its arguments after they've been through bash parsing (quote and escape removal, etc), but when you say "Manually pasting the string ... works" you're saying it's what you want before parsing. If the quotes are there in the echoed string, that means bash didn't recognize them as quotes and remove them. Compare:

string='"quoted string"'
echo $string          # prints the string with double-quotes around it because bash doesnt't recognize them in a variable
echo "quoted string"  # prints *without* quotes because bash recognizes and removes them



回答2:


String mashing executable code is error prone and evil, and there's absolutely no need for it here. It's trivial to pass arguments to an AppleScript by defining an explicit 'run' handler:

on run argv -- argv is a list of strings
    -- do stuff here
end run

which you then invoke like so:

osascript -e /path/to/script arg1 arg2 ...

BTW, if your script requires a fixed number of args, you also write it like this:

on run {arg1, arg2, ...} -- each arg is a string
    -- do stuff here
end run

...

Going further, you can even make the AppleScript directly executable as you would any other shell script. First, add a hashbang as follows:

#!/usr/bin/osascript

on run argv
    -- do stuff here
end run

then save it in uncompiled plain text format and run chmod +x /path/to/myscript to make the file executable. You can then execute it from the shell as follows:

/path/to/myscript arg1 arg2 ...

Or, if you don't want to specify the full path every time, put the file in /usr/local/bin or some other directory that's on your shell's PATH:

myscript arg1 arg2 ...

...

So here's how you should be writing your original script:

#!/bin/sh
the_url="http://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash"
osascript -e 'on run {theURL}' -e 'tell application "Safari" to set URL of document 1 to theURL' -e 'end run' $the_url

Quick, simple, and very robust.

--

p.s. If you'd rather open a URL in a new window rather than an existing one, see the manpage for OS X's open tool.



来源:https://stackoverflow.com/questions/16966117/combining-variables-in-bash-to-form-a-command-sent-to-applescript-using-the-osas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!