如何使用 bash 和 AppleScript 关闭终端窗口而不使用 SystemEvents?

如何使用 bash 和 AppleScript 关闭终端窗口而不使用 SystemEvents?

背景

我正在尝试创建一个脚本,当执行时,打开一个新的终端应用程序窗口执行所需的命令并在完成后关闭窗口。

一种解决方案是在 AppleScript 中使用SystemEvents,以便CMD+w在进程完成时发送到打开的终端窗口,但是,随着 macOS Catalina 的新安全功能,当系统提示将击键发送到终端窗口时,系统需要获得可访问性权限才能发送CMD+w到打开的窗口。因此,这不是一个理想的解决方案。

另一个可能的解决方案是将 Terminal.app 窗口的当前配置文件的从 2 修改shellExitAction为 0,这样当exit传递命令时,窗口就会关闭。但是,由于首选项被缓存,因此在defaults write执行所需命令时不会更新 Terminal 的 plist 文件。我还了解到,不是shellExitActionTerminal plist 文件的全局属性,其层次结构是{ "Window Settings" = { "Basic" = { shellExitAction = 2; }; }; }而不是{ shellExitAction = 2 }因此,这个解决方案没有达到预期的效果。

terminal

#!/bin/bash

# Usage:
#     terminal                   Opens the current directory in a new terminal window
#     terminal [PATH]            Open PATH in a new terminal window
#     terminal [CMD]             Open a new terminal window and execute CMD
#     terminal [PATH] [CMD]      Opens a new terminal window @ the PATH and executes CMD
#
# Example:
#     terminal ~/Code/HelloWorld ./setup.sh

function terminal() {
    local cmd=""
    local wd="$PWD"
    local args="$*"

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

    if [ -d "$1" ]; then
        wd="$1"
        args="${*:2}"
    fi

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

    # Force Terminal window to close on command "exit"
    # Currently, does not achieve the desireable result because the 
    # com.apple.terminal plist file is not reloaded after the 
    # write command is executed.
    sudo defaults read com.apple.terminal shellExitAction &> /dev/null || {
        sudo defaults write com.apple.terminal shellExitAction -int 0
    }

    defaults read com.apple.terminal shellExitAction &> /dev/null || {
        defaults write com.apple.terminal shellExitAction -int 0
    }

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

    osascript <<EOF
tell application "Terminal"
    activate
    tell window 1
        do script "cd $wd ; $cmd ; exit"
        repeat while busy
            delay 1
        end repeat
    end tell
end tell
EOF
}

terminal "$@"

问题

鉴于我上面列出的两种可能的不理想的解决方案,我该如何修改上述脚本,以便在操作do script完成时关闭当前窗口而无需请求可访问性权限?

答案1

终端应用程序可以使用 AppleScript 编写脚本,因此其window对象可以响应命令close例如

tell application id "com.apple.Terminal" to close the front window

从示例脚本中放入上下文中:

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

附录:看法我对后续问题的回答front window它展示了如何使用调用返回的 AppleScript 引用来定位特定窗口(而不仅仅是) do script

相关内容