MacOS – Run AppleScript from bash script

applescriptbashcommand linemacosterminal

If I wanted to run an AppleScript from within a bash script I could call a file with the list of commands that I require to execute.

{some commands}
osascript file.scpt
{other commands}

What, however, if I wanted to run commands that needed to be run in sequence from within bash?

An example would be

echo This will open Google Chrome in Kiosk mode
  osascript -e "tell application \"Google Chrome\""
  osascript -e "activate"
  osascript -e     "tell application \"System Events\""
  osascript -e         "key down {command}"
  osascript -e         "key down {shift}"
  osascript -e         "keystroke \"f\""
  osascript -e         "key up {shift}"
  osascript -e         "key up {command}"
  osascript -e     "end tell"
echo "Google Chrome is now open in Kiosk Mode"

I know this is a very far fetched example, but it works to explain what I am trying to do. Normally, those commands would all be written without their respective escape \ characters all over the place and less " around each command. I'd also have them inside of a .scpt file.

A solution I am aware of, is to rewrite the script using #!/usr/bin/osascript instead of bash and go from there, but I want to be able to blend. I have found that I can test for a script file, if it does exist to create one and append each command I need to that file and then execute the required script file from within bash, but that also defeats the purpose.

There is no way that mid-way through a file, I can swap the shell being used with the shebang line and then swap back after I've executed the commands necessary, is there?

Any insight would be more than welcome.

Best Answer

The argument for osascript -e can contain newlines:

osascript -e 'set x to "a"
say x'

You can also specify multiple -e arguments:

osascript -e 'set x to "a"' -e 'say x'

Or if you use a heredoc, bash interprets three characters (\, $, and `) between <<END and END but no characters between <<'END' and END.

osascript <<'END'
set x to "a"
say x


Since osascript can operate with a heredoc (ie take input from /dev/stdin) then one can just write the script as a whole file and prepend with the correct shebang line:

#!/usr/bin/env osascript

set x to "a"
say x

This also allows you to save your apple script as a actual program in ~/Applications/.app using the following procedure (changing for your script's name):

mkdir -p ~/Applications/<APP_NAME>.app/Contents/MacOS
touch ~/Applications/<APP_NAME>.app/Contents/MacOS/<APP_NAME>
open -A TextEdit ~/Applications/<APP_NAME>.app/Contents/MacOS/<APP_NAME>

Ensure that both the script file in .../MacOS/ and the matches