运行bash脚本后退出终端

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

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

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

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

如果要在命令之后或在一系列命令之后运行exit ,可以使用&&运算符(在前一个命令/命令链成功执行下一个命令时)将其链接到已有的使用; operator(前一个命令/命令链的成功和失败都将执行下一个命令)。

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

 gnome-open  && exit 

* = pdf文件的路径

在脚本末尾的exit put不起作用,因为它只退出运行脚本的bash实例,这是另一个bash实例而不是Terminal的内部bash实例。

如果你想要使用一个脚本,最简单的方法是调用脚本,如下所示:

  && exit 

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

 ./ 

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

 kill -9 $PPID 

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

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

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

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

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

  & disown PPPID=$(awk '{print $4}' "/proc/$PPID/stat") kill $PPPID 
  • PPID

    PPID是父进程id,在本例中是shell( eg /bin/bash

  • PPPID

    PPPID是PPID的父进程ID,在这种情况下是终端窗口

  • & disown

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

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

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

您可以使用exec ./ your-script

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

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

  • 对于您的脚本,这是另一个shell进程 – 就像在没有exec情况下运行脚本时创建第二个 shell进程一样。

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

exec :一个例子

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

 #!/usr/bin/env bash for i in {5..1}; do echo $i; sleep 1; done 

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

 exec ./count 

这将打印数字5,4,3,2和1 ,每秒一个,然后终端窗口关闭。

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

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

如果你不想告诉你的shell用新进程(通过exec )替换它自己,你可以告诉它要坚持下去,但在新进程完成后立即退出。

为此,请运行命令和exit命令,以;分隔; 所以他们可以在一条线上。

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

command ; exit command ; exit vs. command && exit

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

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

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

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

最简单的解决方案是:

 xdg-open file.pdf && exit 

与其他类似命令不同, nohup不需要使命令忽略SIGHUP ,因此xdg-open将退出产生子进程,这是打开pdf文件的首选应用程序。 由于从终端开始的实际过程不再被杀死,因此不需要nohup

&&表示如果上一个命令成功,则运行下一个命令,即返回退出代码0$?=0 ), exit将关闭终端。

您可以获取脚本而不是运行它,例如

 $ cat run.sh exit; $ ./run.sh #will not close $ . ./run.sh # will close 

我个人会执行命令在子shell中打开pdf或其他文件,延迟让文件打开,然后退出。 基本上,这是我测试过的(nohup gnome-open *.pdf &); sleep 2; exit (nohup gnome-open *.pdf &); sleep 2; exit

对此的变化将是nohup gnome-open *.pdf && sleep 2 && exit

要明确回答标题问题,

“运行bash脚本后退出终端”

仅在终端中运行您的脚本

在不查看脚本function的详细信息的情况下,可以使用选项-e ( – 命令)直接在终端内运行脚本,而无需启动shell – 而是使用shell而不是shell:

 gnome-terminal -e ./script.sh 

如果要为脚本提供参数,请使用选项-x--execute )。 有了这个,只需将命令行的其余部分作为命令和参数。

 gnome-terminal -x ./script.sh foo bar 

如果您的脚本退出,则没有交互式shell可以通过等待用户输入来阻止任何内容。

例子

teminal将在其中运行的命令退出后退出 – 就像这样,在sleep运行4秒后关闭,没有shell:

 gnome-terminal -x sleep 4 

当然,您可以使用shell脚本,因为您的脚本无论如何都在使用不同的shell实例。

此外,您可以使用显式脚本运行shell – 它不是交互式的:

 gnome-terminal -x bash -c "echo 'Hello!'; sleep 4"