1

Background

Given the below terminal script, I want to modify the osascript so that instead of targeting the front window I am targeting the specific window that is opened from the AppleScript.

terminal:

#!/bin/bash

# Usage:
#     terminal [CMD]             Open a new terminal window and execute CMD
#
# Example:
#     terminal cd "sleep 100"

terminal() {

    # Mac OS only
    [ "$(uname -s)" != "Darwin" ] && {
        echo 'Mac OS Only'
        return
    }

    local cmd=""
    local args="$*"

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    if [ -n "$args" ]; then
        cmd="$args"
    fi

    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    osascript <<EOF
tell application "Terminal" to tell the front window
    set w to do script "$cmd"
    repeat
        delay 1
        if not busy of w then exit repeat
    end repeat
    close it
end tell
EOF

}

terminal "$@"

Issue

Currently, because of the use of front window I could change the focus after the window pops up to another terminal window then when the do script task completes close it will close the window I am currently focusing and not the window that actually ran the do script.

Ideas

One idea I had in mind was to modify the AppleScript so that we get the window id of the window created from the AppleScript like the below. However, close W does not work.

tell application "Terminal"
    set W to do script ""
    activate
    set S to do script "sleep 5" in W
    repeat
        delay 1
        if not busy of S then exit repeat
    end repeat
    close W
end tell
1

Based on this stackexchange answer you can store the window object then loop through.

You can then close the window you opened whether it is in focus or not.

    osascript <<EOF
    tell application "Terminal"
        set newTab to do script
        set current settings of newTab to settings set "Grass"
        set theWindow to first window of (every window whose tabs contains newTab)

        do script "$cmd" in newTab
        repeat
            delay 0.05
            if not busy of newTab then exit repeat
        end repeat

        repeat with i from 1 to the count of theWindow's tabs
            if item i of theWindow's tabs is newTab then close theWindow
        end repeat
    end tell
EOF

The set current settings of newTab to settings set "Grass" line isn't necessary - it is only to show the relevant window in a different colour.

| improve this answer | |
  • 1
    Apologies for the delay. The thing I noticed is the repeat loop where you reference theWindow's tabs explicitly, thus forcing the collection to be enumerated in every iteration of the loop. Instead, you could assign theWindow's tabs to a variable beforehand, then reference the for the count and the item i of…. In this case, there's only ever one tab, so it doesn't matter, but it in other situations, it'll be quicker and less work for AppleScript. Or, a repeat loop of the form repeat with T in theWindow's tabs means you only need if T = newTab then..., which is quicker still. – CJK Jan 30 at 3:32
2

The way to do this is very simple, and I left a comment to this effect against an earlier question:

Depending what you wish to do, you might find the value of w in your AppleScript to be useful. The window that is created by do script returns an AppleScript reference to it (that you have assigned to w), which will be of the form tab 1 of window id <number>, where <number> is a five-or-so digit id number that remains fixed throughout the lifespan of the window. You have to ignore the fact that the reference always contains tab 1 of..., which is misleading since three tabs contained in a single window will all be tab 1 of... three distinct id numbers.

As you noticed, the close command does not apply to a tab, so you need the window id. The reference created from any do script command gives you tab 1 of window id..., so you will always be able to reference the window which any particular do script command is running in:

tell application id "com.apple.Terminal"
    set T to do script "echo $$" --> btw, there's the pid number of the window's sub-shell
    set W to the id of window 1 where its tab 1 = T
        .
        .
     (* doing other stuff *)
        .
        .
    close window id W
end tell
| improve this answer | |
  • This is neater than my answer – lx07 Jan 24 at 12:02
  • That’s nice of you to say. I already knew how to do it, and I think it’s a specific enough edge case you would probably only know if you have had to do it before. Do you mind me providing a couple of notes about your script or is that patronising ? – CJK Jan 25 at 6:43
  • If you have time please do - I'm a beginner at AppleScript. – lx07 Jan 25 at 7:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.