从shell脚本中关闭终端窗口(Unix)?

58

有没有一种方法可以在shell脚本中关闭终端窗口? 我有一个.command文件,一旦完成任务就应该消失不见。


1
那么为什么一开始要开启它呢? - Ignacio Vazquez-Abrams
1
exit -f 对你不起作用吗?如果您不想让正在运行的命令突然退出,可以使用 nohup - jaypal singh
@IgnacioVazquez-Abrams 我通过双击 .command 文件来运行脚本,功能已完成,操作结束。我不需要终端窗口挂着。这有什么困惑的吗? - ericsoco
7个回答

63

使用exit 0会干净地终止脚本。

终端窗口是否保持打开由用户配置。默认情况下,始终保持打开。要更改此设置:

Terminal.app > Preferences > Profiles > Shell
    - "When the shell exists:"
        > Close if the shell exited cleanly
    - "Ask before closing:"
        (•) Never
        -- OR --
        (•) Only if there are....

当使用“如果Shell干净退出则关闭”选项时,如果退出结果为0(如果没有出现错误,则默认为0),脚本将关闭窗口。


我已经设置了“如果shell干净退出则失败”,但在某个脚本中,我希望终端保持打开状态,直到用户关闭它...有什么解决办法吗? - Jonny
不是直接的(因为.command会在shell中添加;exit),但你可以调用一个不关闭的AppleScript,例如:osascript -e 'tell application "Terminal"' -e activate -e 'do script "run.my.jobs"' -e 'end tell' -- 那个窗口将始终保持打开状态。 - Simon Urbanek
非常酷。感谢@SimonUrbanek。我正在进入Appleverse的世界,这个提示正在帮助我自动化一些琐事。 - Preston
可以工作,但请注意在Yosemite中,此首选项位于终端->首选项->配置文件,然后单击Shell选项卡下。 - mrzzmr

28

由于您不想删除所有终端窗口,首先将窗口名称从“Terminal”更改为其他名称:

echo -n -e "\033]0;我的窗口名称\007"

然后在脚本末尾使用:

osascript -e 'tell application "Terminal" to close (every window whose name contains "我的窗口名称")' &


除非您更改终端首选项,否则仍会要求确认才能关闭它。 - Damasio
7
如果您将结尾处的“&”更改为“& exit”,则不会出现确认对话框。 - Chris Stratton
@KevinM,关闭特定的标签页而不是整个窗口是否可行? - RobertMcReed

18
你可以使用 AppleScript退出 终端应用程序。将以下内容添加到你的脚本中 -
osascript -e 'tell application "Terminal" to quit'

这将会弹出一个确认窗口来关闭应用。您可以在终端偏好设置中禁用此功能。

或者,您也可以使用killall命令退出应用程序。以下方法同样适用。

killall Terminal

注意:

顺便提一下,您可以自由地将上述命令添加到脚本中,以使其按照您的意愿工作。但是,有几个需要注意的问题。首先,这样会限制脚本在不同设备上的能力。其次,最好使用 nohup ,以便正在运行的任何命令都不会因为退出终端应用程序而停止。


+1 我没有 Mac,所以我会假设这是正确答案。 - SiegeX
@SiegeX 哈哈..我知道我们可以从终端运行apple scripts。但是,我真的不知道它是osascript命令。然而,还有另一个很酷的命令叫做killall,它有点类似。谢谢你的信任和赞成。非常感激。 :-) - jaypal singh
3
哇,这真的很激进——删除所有开放脚本肯定不是我建议的。请注意,此行为可以由用户配置,因此如果您将设置更改为设置-> Shell-> 当shell退出时中的更稳妥的"如果shell干净地退出,则关闭",那么您只需要使用exit 0(或什么也不写)即可。 - Simon Urbanek
@SimonUrbanek 没有意识到终端有那个配置选项。那很完美地解决了问题。你的评论其实是一个独立的答案 - 我已经把它写成了下面的答案。如果你想的话,可以复制粘贴到你的名字下面。谢谢! - ericsoco
killall Terminal 会关闭所有终端窗口,这并不是一种友好的选项。 - Kaushik Wavhal

15

这对我有效:

#!/bin/sh

{your script here}

osascript -e 'tell application "Terminal" to close (every window whose name contains ".command")' &
exit

这将适用于关闭仅使用 .command 文件打开的窗口,但是会保留其他终端窗口中已运行的程序。 我知道我几乎总是要么有 sass 或 grunt 在监视着某些东西,所以我不想完全退出终端。


2
当您希望终端退出,但仅在没有更多打开的窗口时,可以使用以下变体:osascript -e 'tell app "Terminal"' -e 'close (every window whose name contains ".command")' -e 'if number of windows = 0 then quit' -e 'end tell' & exit;。多个-e在脚本中添加换行符;对我来说,"\n"存在问题。 - Beejor

8
我发现最好的解决方案是使用Automator创建一个真正的OSX应用程序,无论您的系统配置如何,它都将以相同的方式工作。您可以让Automator运行您的shell脚本,或者您可以将shell脚本本身嵌入Automator中。
以下是操作步骤:
1. 运行Automator(在应用程序中)。 2. 选择“新建文档”,当它要求“选择文档类型”时,选择“应用程序”。 3. 在左侧面板中,选择“实用工具”,然后选择“运行Shell脚本”。 4. 在右侧面板的工作流项中键入脚本命令。您可以调用另一个shell脚本,或直接将命令放在其中。 5. 保存该应用程序,它将成为一个完整的Mac应用程序。您甚至可以从其他应用程序中剪切和粘贴图标,为您的脚本增添一些个性。

点赞。在我的情况下(Mac用户),非常有用且迅速的解决方案。 - Brice Coustillas

8
closeWindow() {
    /usr/bin/osascript << _OSACLOSE_
    tell application "Terminal"
        close (every window whose name contains "YourScriptName")
    end tell
    delay 0.3
    tell application "System Events" to click UI element "Close" of sheet 1 of window 1 of application process "Terminal"
_OSACLOSE_
}

这将关闭你的脚本所在的终端窗口,并保持任何其他终端窗口打开,只要它们的窗口标题不匹配。为了使其正常工作,必须将终端添加到允许使用辅助功能框架的应用程序列表中。您还可以使用重复命令循环遍历终端窗口,并关闭包含第1个表中UI元素“Close”的每个x窗口。

我应该把这个脚本放在哪里? - MikeSchinkel
在脚本完成时,将其粘贴到Bash脚本中并调用closeWindow函数。在调用函数之前,必须将函数粘贴到脚本中。 - user2373121
谢谢您的快速回复! - MikeSchinkel
最佳答案,谢谢! - Fouad
必须将终端激活为辅助功能才能完成此操作。感觉有点像安全漏洞...但现在可以正常工作了,谢谢! - trevore

0
#!/bin/bash -x

{your script here}

. exit 0
kill -9 $PPID

你也可以为你的脚本创建一个快捷方式:

cp yourscript.sh ~/bin/yourshortcutnamewhateveryouwant

然后输入

yourshortcutnamewhateveryouwant

将运行在任何目录中编写的脚本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接