Exit terminal after running a bash script
Solution 1:
If you're opening just one file, you don't really need to use a script, because a script is meant to be an easy way to run multiple commands in a row, while here you just need to run two commands (including exit
).
If you want to run exit
after a command or after a chain of commands, you can chain it to what you have already by using the &&
operator (which on success of the previous command / chain of commands will execute the next command) or by using the ;
operator (which both on success and on failure of the previous command / chain of commands will execute the next command).
In this case it would be something like that:
gnome-open <path_to_pdf_file> && exit
*<path_to_pfd_file> = path of the pdf file
exit
put at the end of a script doesn't work because it just exits the bash
instance in which the script is run, which is another bash
instance than the Terminal's inner bash
instance.
If you want to use a script anyway, the most straightforward way it's to just call the script like so:
<path_to_script> && exit
Or if the script is in the Terminal's current working directory like so:
./<script> && exit
If you really don't want to / can't do that, the second most straightforward way is to add this line at the end of your script:
kill -9 $PPID
This will send a SIGKILL
signal to the to the script's parent process (the bash
instance linked to the Terminal). If only one bash
instance is linked to the Terminal, that being killed will cause Terminal to close itself. If multiple bash
instances are linked to the Terminal, that being killed won't cause Terminal to close itself.
Solution 2:
This script terminates the terminal and thus the shell and himself.
It mercilessly kills all processes. If you have multiple tabs open in a terminal, then these are also closed.
The problem is, if several terminals are opened and these are child processes of gnome-terminal-server
, all terminals will be killed.
In this case, the script should be started in an independent terminal, eg xterm
<your_command> & disown
PPPID=$(awk '{print $4}' "/proc/$PPID/stat")
kill $PPPID
-
PPID
The PPID is the parent process id, in this case the shell (
e.g. /bin/bash
) -
PPPID
The PPPID is the parent process id of PPID, in this case, the terminal window
-
<your_command> & disown
In the bash shell, the disown builtin command is used to remove jobs from the job table, or to mark jobs so that a SIGHUP signal is not sent to them if the parent shell receives it (e.g. if the user logs out).
-
awk '{print $4}' "/proc/$PPID/stat"
Gets the value of the fourth column of the file
/proc/$PPID/stat
(e.g. for/proc/1/stat
it returns 0)
Solution 3:
You can use exec ./your-script
.
A terminal emulator like GNOME Terminal quits when the initial process running inside it--which is usually a shell--quits.
If you are already in a terminal and the only thing you want to do before quitting that terminal is to run a particular script (or program), then this means you no longer really need the shell that's running in it anymore. Thus you can use the shell's exec
builtin to make the shell replace itself with the process created by your command.
- In the case of your script, that's another shell process--just as how a second shell process is created when you run a script without
exec
.
The syntax is exec command
, e.g., exec ./your-script
.
exec
: an Example
For example, suppose I have a shell script called count
, marked executable, and located in the current directory. It contains:
#!/usr/bin/env bash
for i in {5..1}; do echo $i; sleep 1; done
And, in a terminal, I run:
exec ./count
This prints the numerals 5
, 4
, 3
, 2
, and 1
, one per second, and then the terminal window closes.
If you run this from something other than the first process run in your terminal--for example, if you ran bash
first to start another shell instance--then this brings you back to the shell that created that process, rather than quitting the terminal. (This caveat applies equally to exit
-based methods.)
You can use ./your-script; exit
.
If you don't want to tell your shell to replace itself with the new process (via exec
), you can tell it to stick around but quit itself immediately after the new process finishes.
To do this, run your command and the exit
command, separated by ;
so they can be given on one line.
The syntax is command; exit
, e.g., ./your-script; exit
.
command; exit
vs. command && exit
You may notice this looks similar to the ./your-script && exit
method suggested in kos's and heemayl's answers. The difference is that:
-
&&
runs the second command only if the first command reported that it succeeded by returning an exit code of zero. -
;
runs the second command regardless of whether or not the first command reported success.
Which one you want depends on the specific situation. If the command fails, do you want the calling shell (and hosting terminal) to stay up? If so, use &&
; if not, use ;
.
There is also command || exit
, which quits the calling shell only if command
reported failure.
Solution 4:
You could source your script instead of running it e.g
$ cat run.sh
exit;
$ ./run.sh #will not close
$ . ./run.sh # will close