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.

#!/bin/bash
{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

#!/bin/bash
echo
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.


Solution 1:

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
END

Edit:

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

Solution 2:

You can wrap the raw AppleScript in <<EOD... The last EOD, signalling the end of input, has to come at the first position in the line.

(BTW, your applescript seemed to be missing an end tell after activate....)

#!/bin/bash
osascript <<EOD
  tell application "Google Chrome"
      activate
  end tell
  tell application "System Events"
      key down {command}
      key down {shift}
      keystroke "f"
      key up {shift}
      key up {command}
  end tell
EOD

echo "Google Chrome is now open in Kiosk Mode"