Bash Terminal – Run Commands and Allow Typing More Commands

bashgnome-terminalshellterminal

I wrote this script to create multiple tabs in the same terminal window and run commands in them:

#!/bin/bash
#Use the commands as:
#--tab-with-profile=Default --title=<SPECIFY THE TAB TITLE HERE> -e "bash -ic \"<SPECIFY THE COMMAND YOU WANT TO RUN HERE>; bash\"" \
#The ampersand in the end of this file makes sure that the gnome-terminal command is run as a background process

echo "Setting up simulator environment";
service mysqld start;

gnome-terminal \
  --tab-with-profile=Default --title=PROG1 -e "bash -ic \"clear;ls;./prog1; bash disown\"" \
  --tab-with-profile=Default --title=SIMULATOR -e "bash -ic \"clear;ls;./simulator; bash disown\"" \
  --tab-with-profile=Default --title=PROG2 -e "bash -ic \"clear;ls;./prog2; bash disown\"" \
  --tab-with-profile=Default --title=DATA -e "bash -ic \"./data -f \"/home/user/NetBeansProjects/data3.txt\" -p \"6785\"; bash disown\"" \
  --tab-with-profile=Default --title=PROG3 -e "bash -ic \"cd /home/user/NetBeansProjects/simulator;./prog3; bash disown\"" \
&

Problem is, when any of those programs finish running or if I press Ctrl+c to stop any of those programs, the tab closes. I don't want the tab to close. I want the tab to remain open and the bash terminal to be shown so that I can run some other command in the tab. Is there a way to make that happen?

Best Answer

There are two problems;

The first one is that inside each bash -ic command (which by the way doesn't spawn an interactive shell because -c overrides -i, so -i it's safe to be dropped) you're calling bash disown instead of bash, which means nothing and immediately exits on error; so there's no interactive shell keep running that keeps gnome-terminal opened at the end of the outer bash -c command;

(Also mind that you could use exec bash instead of bash at the end of the command, to save some processes.)

The second one is that Ctrl+C SIGINTs all the processess in the same group of the killed process, including the parent bash instance which is supposed to spawn the interactive shell at the end of the command;

To fix this, you can use bash's trap built-in to set bash to spawn another interactive bash instance upon the reception of a SIGINT signal.

In short, this should work:

gnome-terminal \
  --tab-with-profile=Default --title=PROG1 -e "bash -c \"trap 'bash' 2; clear;ls;./prog1; exec bash\"" \
  --tab-with-profile=Default --title=SIMULATOR -e "bash -c \"trap 'bash' 2; clear;ls;./simulator; exec bash\"" \
  --tab-with-profile=Default --title=PROG2 -e "bash -c \"trap 'bash' 2; clear;ls;./prog2; exec bash\"" \
  --tab-with-profile=Default --title=DATA -e "bash -c \"trap 'bash' 2; ./data -f \"/home/user/NetBeansProjects/data3.txt\" -p \"6785\"; exec bash\"" \
  --tab-with-profile=Default --title=PROG3 -e "bash -c \"trap 'bash' 2; cd /home/user/NetBeansProjects/simulator;./prog3; exec bash\"" \
&