I am trying to write a bash script to open certain files (mostly pdf files) using the gnome-open command. I also want the terminal to exit once it opens the pdf file.
I have tried adding exit to the end of my script however that does not close the terminal. I did try to search online for an answer to my question but I couldn't find any proper one, I would really appreciate it if you guys could help.
I need an answer that only kills the terminal from which I run the command not all the terminals would this be possible? The previous answer which I accepted kills all the terminal windows that are open. I did not realize this was the case until today.
107 Answers
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> && exitOr if the script is in the Terminal's current working directory like so:
./<script> && exitIf 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 $PPIDThis 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.
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 $PPPIDPPID
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> & disownIn 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/statit returns 0)
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; doneAnd, in a terminal, I run:
exec ./countThis 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.
You could source your script instead of running it e.g
$ cat run.sh
exit;
$ ./run.sh #will not close
$ . ./run.sh # will close Personally I would execute the command to open pdf or other files in subshell, put a delay to let the files open, and then exit. Basically, here's what I've tested (nohup gnome-open *.pdf &); sleep 2; exit
Variation on this would be nohup gnome-open *.pdf && sleep 2 && exit
The simplest solution would be:
xdg-open file.pdf && exitUnlike other similar command nohup is not needed to make the command ignoring SIGHUP, the reason being xdg-open will exit spawning a child process which is preferred application to open the pdf file. As the actual process started from the terminal is no longer there to be killed, nohup is not needed.
&& indicates the next command will be run if the previous command is successful i.e. returns the exit code 0 ($?=0) and exit will simply close the terminal.
To explicitly answer the title question,
"Exit terminal after running a bash script":
Run only your script in the terminal
Without looking at the details what the script does, a script can be directly run inside a terminal with the option -e (--command), without starting a shell - it is used instead of the shell then:
gnome-terminal -e ./script.shUse the option -x (--execute) when you want to provide arguments to the script. With this, just the whole remainder of the commandline is taken as command and arguments.
gnome-terminal -x ./script.sh foo barIf your script exits, there is no interactive shell that could hold up anything by waiting for user input.
Examples
The teminal will just exit after the command running in it exits - like this, closing after sleep has run 4 seconds, with no shell:
gnome-terminal -x sleep 4Of course, you can stil use shell scripting, because your script is using a different shell instance anyway.
Also, you can run a shell with an explicit script - it will not be interactive:
gnome-terminal -x bash -c "echo 'Hello!'; sleep 4"