How to focus parent terminal tab of shell script for input?

I have a zsh script where I prompt for user input every 15 minutes. How can I make the tab of Terminal that the script is running in open up / focus? open -a Terminal just opens the whole window.

I'm aware of this trick to get current application and re-open it, is there a way to extend it to tabs/sessions?

term=$(/usr/bin/osascript -e "copy path to frontmost application as text to stdout")
/usr/bin/osascript -e 'tell application $term to activate'

Also aware of this trick to go back to an old tab, although (1) I couldn't get it to work and (2) I need the data in stdout so zsh can use it.

osascript \
    -e 'tell application "Terminal" to set oldTab to the selected tab of the front window' \
    -e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down' \
    -e 'delay 1' \
    -e 'tell application "Terminal" to set selected of oldTab to true'

Solution 1:

Based on your reply of "Yes, precisely. Well put." to my comment under the OP...

Could you please clarify what it is you are trying to do? Are you trying to have the shell script itself refocus the tab/window in which the shell script is running? In other word, do you want to start the shell script and when the 15 minutes are up, regardless of what app is frontmost, you want Terminal to come frontmost to the tab/window in which the shell script is running and this all be done programmatically?

The following example AppleScript code used in conjunction with osascript in a zsh shell script should do as wanted. Obviously the value of the sleep command is just for testing purposes, use whatever it is you are now using as the timer within your current zsh shell script.

#!/bin/zsh

    # First line of code of shell script.

winID="$(osascript -e 'id of window 1 of app "Terminal"')"

    # Function to refocus window of running script.

refocusWindow() {

        # Code to refocus window of the
        # running shell script using the 
        # window id retrieved from the first 
        # line of code in the shell script.

    osascript <<EOS
    tell app "Terminal"
        set frontmost of windows whose id = $winID to true
        activate
    end tell
EOS
}

# Do some stuff...
# Your other code goes here.

sleep 5

refocusWindow

Notes:

In Terminal, it does not matter how may tabs/windows there are as there is only one tab per window, even if the window appears to have multiple tabs. In other words, asking Terminal to count windows and count tabs of windows will return the same number. Thus there it no need to loop thru tabs to achieve the goal herein, just windows, and actually in this case there really is no need to loop thru windows.

Note that macOS Sierra what the last version in which Terminal supported multiple tabs of a window programmatically. In other words, from the UI a single window with two tabs there would be tab 1 of window 1 and tab 2 of window 1, but since macOS High Sierra from the UI a single window with two tabs there would be tab 1 of window 1 and tab 1 of window 2, and thus no longer the need to loop thru tabs.

There is all so no need to do something like set selected of tab j of window i to true as once a given window is set frontmost, the value of tab 1 of window i is already set to true as a result.

The example shell script and AppleScript code, shown above, was tested in Terminal as an executable shell script under macOS Catalina and macOS Big Sur with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.

  • 1 Assumes necessary and appropriate setting in System Preferences > Security & Privacy > Privacy have been set/addressed as needed.

As we do not know how you have your zsh shell script coded, you'll have to work in the code presented herein to suite your needs.

Solution 2:

This is a little awkward since I can't run this code from within your script (nor within an applescript) but this osascript should allow you to specify a desired tab (tp) and switch to it from any other within the same window.

osascript -e '
tell application "Terminal" to set tp to item 1 of (tabs of window 1 whose selected is true)
tell application "System Events" to tell process "Terminal" to keystroke "t" using command down
delay 1
tell application "Terminal" to set selected of tp to true'

I think your issue was just a syntax one: e.g. selected tab versus tab whose selected is true.

Each line does the following:

  • Sets variable tp to the active tab
  • Creates a new tab using system events (which becomes the active tab)
  • Delay 1
  • Makes tp the active tab

The variable tp will resemble this:

--> tab 3 of window id 360 of application "Terminal"

Note, there are some alternatives to setting tp to the active tab but they're more complex.