运行 bash 脚本后退出终端

Rum*_*esh 21 command-line bash scripts

我正在尝试编写一个bash脚本来使用该gnome-open命令打开某些文件(主要是 pdf 文件)。我还希望终端在打开 pdf 文件后退出。

我曾尝试添加exit到我的脚本的末尾,但这并没有关闭终端。我确实尝试在网上搜索我的问题的答案,但找不到任何合适的答案,如果你们能提供帮助,我将不胜感激。

我需要一个只杀死我运行命令的终端而不是所有终端的答案,这可能吗?我接受的上一个答案会杀死所有打开的终端窗口。直到今天我才意识到情况是这样。

kos*_*kos 20

如果你只打开一个文件,你真的不需要使用脚本,因为脚本是一种连续运行多个命令的简单方法,而在这里你只需要运行两个命令(包括exit) .

如果你想exit在一个命令或一个命令链之后运行,你可以通过使用&&操作符(在前一个命令/命令链成功时执行下一个命令)或使用;操作符(在前一个命令/命令链成功和失败时都将执行下一个命令)。

在这种情况下,它会是这样的:

gnome-open <path_to_pdf_file> && exit
Run Code Online (Sandbox Code Playgroud)

*<path_to_pfd_file> = pdf 文件的路径

exitput 在脚本末尾不起作用,因为它只是退出bash运行脚本的实例,该bash实例是终端内部bash实例之外的另一个实例。

如果您无论如何都想使用脚本,最直接的方法就是像这样调用脚本:

<path_to_script> && exit
Run Code Online (Sandbox Code Playgroud)

或者,如果脚本在终端的当前工作目录中,如下所示:

./<script> && exit
Run Code Online (Sandbox Code Playgroud)

如果你真的不想/不能那样做,第二种最直接的方法是在你的脚本末尾添加这一行:

kill -9 $PPID
Run Code Online (Sandbox Code Playgroud)

这将向SIGKILL脚本的父进程(bash链接到终端的实例)发送信号。如果只有一个bash实例链接到终端,则该实例被杀死将导致终端自行关闭。如果多个bash实例链接到终端,则被杀死不会导致终端自行关闭。

  • SIGTERM 信号被发送到一个进程以请求其终止。与 SIGKILL 信号不同,它可以被进程捕获并解释或忽略。这允许进程在适当时执行良好的终止释放资源和保存状态。SIGINT 几乎与 SIGTERM 相同。 (2认同)

A.B*_*.B. 6

这个脚本会终止终端,从而终止 shell 和他自己。

它无情地杀死所有进程。如果您在终端中打开了多个选项卡,则这些选项卡也会关闭。

问题是,如果打开了多个终端并且这些是 的子进程gnome-terminal-server,则所有终端都将被杀死。

在这种情况下,脚本应该在一个独立的终端中启动,例如 xterm

<your_command> & disown

PPPID=$(awk '{print $4}' "/proc/$PPID/stat")
kill $PPPID
Run Code Online (Sandbox Code Playgroud)
  • PPID

    PPID 是父进程 ID,在这种情况下是 shell ( e.g. /bin/bash)

  • PPPID

    PPPID 是 PPID 的父进程 id,在本例中为终端窗口

  • <your_command> & disown

    在 bash shell 中,disown 内置命令用于从作业表中删除作业,或标记作业,以便在父 shell 接收到 SIGHUP 信号时(例如,如果用户注销)不会向它们发送 SIGHUP 信号。

  • awk '{print $4}' "/proc/$PPID/stat"

    获取文件第四列的值/proc/$PPID/stat(例如,/proc/1/stat它返回 0)

  • @AB 你之前说过这只会杀死当前的终端窗口,而不是其他任何窗口。我今天在打开两个终端窗口的情况下使用了这个脚本,一旦我运行脚本,它们都被杀死了。 (3认同)

Eli*_*gan 6

您可以使用.exec ./your-script

像 GNOME 终端这样的终端模拟器会在其中运行的初始进程(通常是 shell)退出时退出。

如果您已经在终端中,并且在退出该终端之前您唯一想做的就是运行特定的脚本(或程序),那么这意味着您不再真正需要在其中运行的 shell。因此,您可以使用 shell 的exec内置命令使 shell您的命令创建的进程替换自身

  • 在你的脚本的情况下,这是另一个shell进程-就像如何第二,当你不运行的脚本创建shell进程exec

语法是,例如,。exec commandexec ./your-script

exec: 一个例子

例如,假设我有一个名为 的 shell 脚本count,标记为可执行文件,位于当前目录中。它包含了:

#!/usr/bin/env bash
for i in {5..1}; do echo $i; sleep 1; done
Run Code Online (Sandbox Code Playgroud)

而且,在终端中,我运行:

exec ./count
Run Code Online (Sandbox Code Playgroud)

这将每秒打印一个数字54321,然后终端窗口关闭。

如果您从终端中运行的第一个进程以外的其他进程运行它——例如,如果您bash首先运行以启动另一个 shell 实例——那么这会将您带回创建进程的 shell ,而不是退出终端。(此警告同样适用于exit基于方法。)

您可以使用../your-script; exit

如果您不想告诉您的 shell 用新进程(通过exec)替换自己,您可以告诉它继续存在,但在新进程完成后立即退出。

为此,请运行您的命令和exit命令,用 分隔,;以便它们可以在一行中给出。

语法是command; exit,例如,。./your-script; exit

command; exit 对比 command && exit

您可能会注意到这看起来类似的建议方法科斯的heemayl的答案。不同之处在于:./your-script && exit

  • &&仅当第一个命令通过返回零退出代码报告它成功时才运行第二个命令。
  • ; 无论第一个命令是否报告成功,都会运行第二个命令。

你想要哪个取决于具体情况。如果命令失败,您是否希望调用 shell(和托管终端)保持运行?如果是这样,请使用&&; 如果没有,请使用;.

还有command || exit,只有在command报告失败时才退出调用 shell 。