101

I have a script in file bla.sh and it is executable. When I click on it, the script is executed and the window is closed. I'd like the window to stay open.

Something like command cmd /k** command in Windows.

P.S. I don't want to use pause, but I want to able to write more commands after the script was executed.

0

9 Answers 9

118

Put $SHELL at the end of your script:

alt text

A small flaw: since gnome-terminal isn't running the bash as it's shell, it will regard it as an application and display a warning about it when you try to close the terminal:

There is still a process running in this terminal
Closing the terminal will kill it.

I've found no nice way to hide this warning. If you want, you can disable it entirely by running:

gconftool --set /apps/gnome-terminal/global/confirm_window_close --type boolean false

This doesn't happen if you're using xterm instead of gnome-terminal; should it bother you.

6
  • 28
    You can use exec $SHELL instead of just $SHELL to make the warning go away without changing settings. Jan 29, 2013 at 10:54
  • 3
    But this solution creates an extra shell / process. Can this be avoided?
    – lucasvc
    Sep 5, 2016 at 10:26
  • I don't know of a way to do this, no. The problem is that you lose your handle on standard IO once the first bash process is finished, so you would have to do some trickery with a daemon that passes on these handles, which would then be more error-prone and annoying. Sep 5, 2016 at 12:04
  • On my system, echo $SHELL shows that the SHELL variable contains /bin/bash. Therefore, using bash in place of $SHELL is identical. Also, I've determined that all 3 of these at the end will keep the terminal open: bash, eval bash, exec bash, but only the latter, exec bash, will then allow you to close the terminal without it warning you a process is still running. Therefore, the best to use is exec bash or exec $SHELL, as @AndreaCorbellini says in his comment above. Feb 11, 2020 at 22:51
  • I made this an answer, since it should stand on its own as an answer: askubuntu.com/questions/20330/…. Feb 11, 2020 at 23:02
19

Using Gnome Terminal

Using gnome-terminal appending ;bash at the end of the command string and calling the script with -c option works. For example:

gnome-terminal -e "bash -c ~/script.sh;bash"

This does the following:

  1. opens gnome-terminal
  2. executes the script script.sh
  3. shows the bash prompt after the script has finished.

You can exit the gnome-terminal window by closing the window or type exit at the bash prompt. Or you can type more commands as requested.

2
  • 1
    -e is deprecated, so what do we do now? # Option “-e” is deprecated and might be removed in a later version of gnome-terminal. # Use “-- ” to terminate the options and put the command line to execute after it. Feb 11, 2020 at 6:00
  • 1
    This is the only solution that I could get to work (Ubuntu 20.04), however it seems to fail if I add more commands in between, i.e. script.sh;command;bash. Any idea why or how I should add more commands in between?
    – Kvothe
    Nov 19, 2020 at 15:57
18

If you have access to the script, you may also add the following code at the end:

read

That code will wait for an input before closing, so the terminal will stay open until you press Enter.

1
  • 1
    I often use bash at the end, but read allows me to close the window just with ctrl+c or enter, instead of ctrl+shift+w or alt+f4. This is convenient when you iterate rapidly on your script.
    – hsandt
    May 23, 2018 at 16:37
10

Use bash's --init-file option with a temporary pipe:

bash --init-file <(echo './<script_name>')

Ex:

bash --init-file <(echo './bla.sh')
4
8

If you are using xterm use -hold.

1
  • additionally, if you use konsole --hold can work, note the 2 dashes as a single one makes each letter interpret as its own argument
    – My1
    Jul 12, 2023 at 10:50
3

Using xterm and appending ;bash at the end of the command string works. For example:

xterm -e "bash ~/script.sh;bash"

This does the following:

  1. opens xterm
  2. executes the script script.sh
  3. shows the bash prompt after the script has finished.

You can exit the xterm window by closing the window or type exit at the bash prompt. Or you can type more commands as requested.

3

TLDR;

Use exec bash; or exec $SHELL; at the end of a command to keep the terminal open after running the command.

Details and sample test code

There isn't an answer showing exec bash as the right answer, but there should be, so here it is. This answer is borrowed in part from @Karsvo's answer, @Stefano Palazo's answer, and @Andrea Corbellini's comment under Stefano's answer.

On my system (this was last tested and checked on Ubuntu 20.04), echo $SHELL shows that the SHELL variable contains /bin/bash. which bash shows that the bash executable is located in /usr/bin/bash, however. BUT, /user/bin/bash and /bin/bash are identical executables, as proven by having the same sha256sum:

$ which bash
/usr/bin/bash

$ sha256sum $(which bash)
04a484f27a4b485b28451923605d9b528453d6c098a5a5112bec859fb5f2eea9  /usr/bin/bash

$ sha256sum $SHELL
04a484f27a4b485b28451923605d9b528453d6c098a5a5112bec859fb5f2eea9  /bin/bash

Therefore, using bash in place of $SHELL is identical. Also, I've determined that all 3 of these at the end will keep the terminal open: bash, eval bash, exec bash, but only the latter, exec bash, will then allow you to close the terminal without it warning you a process is still running. Therefore, the best to use is exec bash or exec $SHELL, as @AndreaCorbellini says in his comment.

Test 1: this will work as expected

Here's what this might look like in a use-case of having a script to open up two new gnome-terminal tabs already cded into your ~/some_dir directory:

Add to the bottom of your ~/.bashrc file:

open_default_tabs() {
    gnome-terminal --tab -- bash -ic "cd ~/some_dir; exec bash;"
    gnome-terminal --tab -- bash -ic "cd ~/some_dir; exec bash;"
}

OR: again, you can use exec $SHELL here instead as well:

open_default_tabs() {
    gnome-terminal --tab -- bash -ic "cd ~/some_dir; exec $SHELL;"
    gnome-terminal --tab -- bash -ic "cd ~/some_dir; exec $SHELL;"
}

Then in any gnome-terminal already open, re-source your ~/.bashrc file with . ~/.bashrc, then run this command with:

open_default_tabs

...and you'll see your original gnome-terminal tab plus two new tabs, with both of the two new tabs already cded into the ~/some_dir directory.

If you delete the exec bash; or exec $SHELL; portion from the end of each of the commands above, however, then re-source your ~/.bashrc file with . ~/.bashrc, then run the open_default_tabs command again, you'll see that the tabs flicker open then immediately close. All you'll see is a couple quick flashes. The exec bash; or exec $SHELL; part at the end is required to keep these new tabs open.

Test 2: this proves that exec bash; works. BUT, the behavior regarding gnome-terminal isn't quite as expected. To solve that, see my more-complicated answer and work-around in my other answer here.

In test.sh:

gnome-terminal --tab -- bash -ic "cd ~/some_dir; exec bash;"
gnome-terminal --tab -- bash -ic "cd ~/some_dir; exec bash;"

Ensure some_dir exists, and make test.sh executable:

mkdir -p ~/some_dir
chmod +x test.sh

Run it:

./test.sh

Notice the two windows (not tabs, in this case, due to a problem in gnome-terminal) which were just opened stay open. Delete exec bash; above and you'll see they don't--they instantly close--so fast you won't even see them open. This proves exec bash; is working perfectly. The gnome-terminal behavior isn't quite as expected, but that has nothing to do with exec bash;, which works just fine. Again, see my other answer here for a full work-around to the problem specific to gnome-terminal in this case.

Related:

  1. Here's why I REALLY needed this information! This is my "other answer" I mention above: Open Terminal with multiple tabs and execute application
3
  • exec bash seems promising, but it only seems to work as described if the script has been executed in terminal via file dialog, not if the terminal was open to begin with and ./path/to/script.sh was typed. Currently I’m using a combination of readlink and checking $COLORTERM to check if exit would close the terminal window, and use exec bash only in this case. Jan 5, 2021 at 5:03
  • @SebastianSimon, I've massively updated my answer. What you are experiencing is a problem with gnome-terminal, not a problem with exec bash; at the end of a command, which works just fine. Please see my Test 1 and Test 2 sections added to my answer above, and my other answer here for the fix to your gnome-terminal problem. Jan 5, 2021 at 7:27
  • I’ve read both answers now, but concerning the exec bash behavior when executing a shell script via file terminal, the first answer only links to the second one, and the second answer doesn’t seem to address this in detail; instead it talks more about setting titles by calling gnome-terminal. Not sure what exactly I should be looking at. My workaround works just fine, anyway. Minor nitpick: “as proven by having the same sha256sum — or more directly: [[ '/bin/bash' -ef '/usr/bin/bash' ]] or [[ "$(readlink -f '/bin/bash')" = "$(readlink -f '/usr/bin/bash')" ]]. Jan 9, 2021 at 14:25
2
xterm -e bash --rcfile bla.sh

This will run the script in a new window, and even give you control of the window after it is finished.

However the new window will not load ~/.bashrc as normal, since we ran bla.sh instead. This can be remedied by putting

. ~/.bashrc

at the top of bla.sh

0

I have found out that gnome-terminal is a bit bad on doing this, xterm is more serene to do this task without poping up questions. For instance, I executed a command "date" and it was COVERED BY A BLUE POPUP from gnome-terminal saying that the child process exit fine, impeding me to see the output of date.

Gnome-terminal should add a menu "Disable all terminal messages"

IMPORTANT: you should be in the execution directory where all dependences are found from '.'

Type this, and the terminal will be kept in a new process:

xterm -fa Monospace -fs 10 -e "bash -c 'mycommand arg1 arg2 argn';bash" &

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .