Ubuntu – Close one specific GNOME Terminal command

bashcommand linegnome-terminal

I run a loop like this (duration one hour):

#!/bin/bash
gnome-terminal --geometry=50x30 --working-directory=/$HOME/TEST --title terminal1 -e  ' sh -c "./FirstAPP; exec bash"'
while true; do
    if [ ! pgrep SecondAPP ]; then
        gnome-terminal --geometry=50x30 --working-directory=/$HOME/TEST --title terminal2 -e  ' sh -c "./SecondAPP; exec bash"'
        for ((i=0; i<3600; i+=5)); do
            sleep 5
            if [ ! pgrep SecondAPP ]; then
                break
            fi
        done
        killall -9 SecondAPP > /dev/null 2>&1 
    # Iwant here a command that closes the gnome-terminal "terminal2"
    fi
    sleep 5
done

I run this loop and I noticed that in the terminal2 the process got killed but the terminal stays open. Is there a flag or something to close that terminal2?

Or is my implementation wrong?

PS. I am a newbie in Ubuntu, I looked up closing specific terminal, however I dont think it apllies to my case.

Best Answer

You are killing the program SeondApp, but you are not killing the terminal it is running in. The two are separate things. For example, this is the process tree of running gedit in a terminal:

$ gedit &
[1] 13064
$ pstree -s 13064
systemd───systemd───gnome-terminal-───bash───gedit───4*[{gedit}]

Ignore the systemd, that's the init process, everything running on your machine is a child of systemd. Then, what you see there is that gnome-terminal has launched bash which then runs gedit. If you now kill gedit, that won't affect its parents. However, if you kill one of the parents, that will also kill the child.

Normally, what you would do is to use $!, a special variable that holds the PID of the last process launched to the background. Unfortunately, that doesn't with gnome-terminal which seems to have some sort of complicated launching procedure:

$ gnome-terminal &
[1] 23861
$ ps aux | grep 23861
terdon   24341  0.0  0.0   8684  2348 pts/11   S+   10:59   0:00 grep --color 23861
$ pgrep gnome-terminal
23866

As you can see above, gnome-terminal seem to re-launch itself after launching and uses a different PID. No idea why, but another good reason to use a different terminal.

So, since the standard approach won't work, we need a workaround. What you can do is use kill -$PID which will kil all processes in the process group (from man kill):

-n  where n is larger than 1.  All processes in process  group  n  are
    signaled.   When  an argument of the form '-n' is given, and it is
    meant to denote a process group, either a signal must be specified
    first,  or  the argument must be preceded by a '--' option, other‐
    wise it will be taken as the signal to send.

Putting all this together, here's a working version of your script:

#!/bin/bash
gnome-terminal --geometry=50x30 --working-directory=/$HOME/TEST --title terminal1 \
               -e  ' sh -c "./FirstAPP; exec bash"'
while true; do
    if ! pgrep SecondAPP; then
        gnome-terminal --geometry=50x30 --working-directory=/$HOME/TEST \
            --title terminal2 -e  'SecondAPP' &
        for ((i=0; i<3600; i+=5)); do
          sleep 5
          if ! pgrep SecondAPP; then
            break
          fi
        done
        ## Now, get the PID of SecondAPP
        pid=$(pgrep SecondAPP)
        ## Using -$pid will kill all process in the process group of $pid, so
        ## it will kill SecondAPP and its parent process, the terminal.
        kill -- -$pid
    fi
    sleep 5
done

Note that I also remove the [ ] around ! pgrep since that was wrong syntax.


I don't see why you are launching terminals at all though. Here's the same idea, without terminals:

#!/bin/bash

$HOME/TEST/FirstAPP
while true; do
    if ! pgrep SecondAPP; then
      #$HOME/TEST/SecondAPP &
      SecondAPP &
      pid=$!
        for ((i=0; i<3600; i+=5)); do
          sleep 5
          if ! pgrep SecondAPP; then
            break
          fi
        done
        kill $pid
    fi
    sleep 5
done

Finally, this feels like a strange way of doing things. You might want to ask a new question, explain what you are trying to do and why and we can see if we can find a simpler approach for whatever it is you need.