Applescript "expected then but found identifier"

At present, I have a very simple bash script which calls osascript -e a bunch of times; it looks like this (newlines added for readability):

#!/bin/sh
osascript \
  -e 'tell application "Terminal" to activate' \
\
  -e 'set allWindows to number of windows' \
  -e 'set newTab to true' \
\
  -e 'repeat with i from 1 to allWindows' \
  -e '  set allTabs to number of tabs of window i' \
  -e '  repeat with j from 1 to allTabs' \
  -e '    if custom title of tab j of window i contains "Hi" then' \
  -e '      set frontmost of window i to true' \
  -e '      set selected of tab j of window i to true' \
  -e '      set newTab to false' \
  -e '    end if' \
  -e '  end repeat' \
  -e 'end repeat' \
\
  -e 'if newTab then' \
  -e '  tell application "System Events" to tell process "Terminal" to keystroke "t" using command down' \
  -e '  tell application "Terminal"' \
  -e '    do script ("tabname $2") in selected tab of the front window' \
  -e '    set custom title of selected tab of the front window to "$2"' \
  -e '  end tell' \
  -e 'end if' \
\
  -e 'tell application "Terminal" to do script ("$1") in selected tab of the front window'

The idea behind this is to let me call something like ~/term.sh pwd Hi to open a new terminal tab with the title "Hi" and call pwd inside it.

The only problem is that it errors with 222:227: syntax error: Expected “then”, etc. but found identifier. (-2741). I assume this means an if is missing a then, but can't see any of those. The other thought I had is that 222:227 indicates columns, but again I don't see how those columns of the command are wrong.

Is there anyone who can point me in the right direction here please?


Solution 1:

Before you try running a non-trivial script using osascript, first try compiling it (and running it, if feasible) in Script Editor.

When I compiled your script in Script Editor, it revealed that your script is trying to use the term custom title—a Terminal-specific term—without targeting Terminal, so the term isn't available. Extend your first line, tell … to …, into a tell block:

tell application "Terminal Latest"
    activate

    set allWindows to number of windows
    set newTab to true

    repeat with i from 1 to allWindows
        set allTabs to number of tabs of window i
        repeat with j from 1 to allTabs
            if custom title of tab j of window i contains "Hi" then
                set frontmost of window i to true
                set selected of tab j of window i to true
                set newTab to false
            end if
        end repeat
    end repeat
end tell

if newTab then
    tell application "System Events" to tell process "Terminal" to keystroke "t" using command down
    tell application "Terminal Latest"
        do script ("tabname $2") in selected tab of the front window
        set custom title of selected tab of the front window to "$2"
    end tell
end if

tell application "Terminal Latest" to do script ("$1") in selected tab of the front window

But you're going to find that this code still doesn't work, because you're trying to use shell variables $1 and $2 inside single-quoted strings, where the shell won't interpret them. So you'll also need to break up the quoting of those lines, e.g., in your osascript command arguments change

-e 'do script ("tabname $2") in selected tab of the front window'

to

-e 'do script "tabname '"$2"'" in selected tab of the front window'

[Untested.]

Also, the parentheses were unnecessary.

However, if you're storing this in a shebang script file, you don't need to use a shell to run osascript. You can change the first line to

#!/usr/bin/osascript

and then just put your AppleScript code after that, without the -e options, surrounding single-quoting or line-continuation backslashes.

Finally, since AppleScript supports the hash # comment character, you can edit, compile and run (as appropriate) osascript shebang scripts in Script Editor.

Update: A minute later I realized you want to pass command-line arguments to the script. So, you do want to use a shell to run osascript for your case. However, you can simplify things by using a Here document to place the script inline:

osascript<<EOF
    <your script here>
EOF

Variables/arguments will be expanded.