How do I make a "stop" script in bash that closes gnome-terminal tabs that I had previously opened with a different bash script? - linux

I have a script called start.sh:
#!/bin/bash
gnome-terminal --tab -- bash -c "./application1; bash"
gnome-terminal --tab -- bash -c "./application2; bash"
gnome-terminal --tab -- bash -c "./application3; bash"
This script opens three new tabs in the current terminal window and runs a unique application in each one.
Now I want to write stop.sh, which will kill the three application processes and then close the three tabs they were running in. So the first three commands in the script will probably be:
pkill -9 application1
pkill -9 application2
pkill -9 application3
But how do I then close the gnome-terminal tabs I had previously opened in the other script?

Each application has a bash as the parent process, so you should kill the parent as well.
You may find the parent with ps command:
APP1PID=`pgrep application1`
APP1PPID=`ps j $APP1PID | awk 'NR>1 {print $1}'`
kill -9 $APP1PPID
It is sufficient to kill the parent process, it will kill all children as well.

Related

Linux Gonme: Start multiple terminals and execute a command in each one

How can I implement the following scenario in Ubuntu Linux?
I want to go to my console, then execute ./startdev.sh and then
1) Terminal 1 pops up, starts /home/foobar/bla1.sh
2) Terminal 2 pops up, starts /home/foobar/bla2.sh
3) Terminal 3 pops up, starts /home/foobar/bla3.sh
I already figured that the command "gnome-terminal & disown" starts a new terminal.
However, until now, I don't know how to run a command in that terminal.
I accept any answer that gives me either the entire implementation for startdev.sh or a list of commands that I can use.
Thank you!
Try this content for startdev.sh:
#!/bin/bash
gnome-terminal --command=/home/foobar/bla1.sh & disown
gnome-terminal --command=/home/foobar/bla2.sh & disown
gnome-terminal --command=/home/foobar/bla3.sh & disown
But it is not clear for me why you need to disown the launched processes.
Try this script
If you need to simultaneously pop all terminals
#!/bin/bash
gnome-terminal -e "bash -c '/home/foobar/bla1.sh; sleep 10'" | gnome-terminal -e "bash -c '/home/foobar/bla2.sh; sleep 10'" | gnome-terminal -e "bash -c '/home/foobar/bla3.sh; sleep 10'"
else if you need to run commands one by one terminal then .,
#!/bin/bash
gnome-terminal -e "bash -c '/home/foobar/bla1.sh; sleep 10'"
gnome-terminal -e "bash -c '/home/foobar/bla2.sh; sleep 10'"
gnome-terminal -e "bash -c '/home/foobar/bla3.sh; sleep 10'"
this script will open multiple terminals and execute the command given within the quotes and i have used sleep to hold the terminal from exiting if not added gnome-terminal will execute command and exit immediately.

Can i wait for a process termination that is not a child of current shell terminal?

I have a script that has to kill a certain number of times a resource managed by a high avialability middelware. It basically checks whether the resource is running and kills it afterwards, i need the timestamp of when the proc is really killed. So i have done this code:
#!/bin/bash
echo "$(date +"%T,%N") :New measures Run" > /home/hassan/logs/measures.log
for i in {1..50}
do
echo "Iteration: $i"
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
if [ -n "$PID" ]; then
echo "$(date +"%T,%N") :Killing $PID" >> /home/hassan/logs/measures.log
ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print "kill -9 " $2'} | sh
wait $PID
else
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
until [ -n "$PID" ]; do
sleep 2
PID=`ps -ef | grep "/home/hassan/Desktop/pcmAppBin pacemaker_app/MainController"|grep -v "grep" | awk {'print$2'}`
done
fi
done
But with my wait command i get the following error message: wait: pid xxxx is not a child of this shell
I assume that You started the child processes from bash and then start this script to wait for. The problem is that the child processes are not the children of the bash running the script, but the children of its parent!
If You want to launch a script inside the the current bash You should start with ..
An example. You start a vim and then You make is stop pressing ^Z (later you can use fg to get back to vim). Then You can get the list of jobs by using the˙jobs command.
$ jobs
[1]+ Stopped vim myfile
Then You can create a script called test.sh containing just one command, called jobs. Add execute right (e.g. chmod 700 test.sh), then start it:
$ cat test.sh
jobs
~/dev/fi [3:1]$ ./test.sh
~/dev/fi [3:1]$ . ./test.sh
[1]+ Stopped vim myfile
As the first version creates a new bash session no jobs are listed. But using . the script runs in the present bash script having exactly one chold process (namely vim). So launch the script above using the . so no child bash will be created.
Be aware that defining any variables or changing directory (and a lot more) will affect to your environment! E.g. PID will be visible by the calling bash!
Comments:
Do not use ...|grep ...|grep -v ... |awk --- pipe snakes! Use ...|awk... instead!
In most Linux-es you can use something like this ps -o pid= -C pcmAppBin to get just the pid, so the complete pipe can be avoided.
To call an external program from awk you could try system("mycmd"); built-in
I hope this helps a bit!

Bash: Using SSH to start a long-running remote command and collect its PID

When I do the following, then I have to press CTRL-c afterwards or the shell acts weird. Left/right arrows keys e.g. doesn't move correctly and the text is messed up.
# read -r pid < <(ssh 10.10.10.46 'sleep 50 & echo $!') ; echo $pid
2135
# Killed by signal 2.
^C
#
I need this for a script, so I'd like to know why CTRL-c is needed and is it possible to work around it?
Update
It looks like it opens an extra Bash shell, and that is the one that needs to be exited.
The command I am actually interesting in is
read -r pid < <(ssh 10.10.10.46 "mbuffer -4 -v 0 -q -I 8023 > /tmp/mtest & echo $!"); echo $pid
Try this instead:
read -r pid \
< <(ssh 10.10.10.46 'nohup mbuffer >/tmp/mtest </dev/null 2>/tmp/mtest.err & echo $!')
Three important changes:
Use of nohup (you could also get a similar effect with the bash built-in disown)
Redirection of stdin and stderr to files (preventing them from holding handles that connect, eventually, to your terminal).
Use of single quotes for the remote command (with double-quotes, expansions happen before ssh is started, so the $! you get is the PID of the most recently started local background process).

How to run a pkill when invoking a shell to execute a string of commands?

To automate a system administration task, I wrote down the following line of shell code:
bash -c 'pkill -TERM -f java; true'
The problem is that pkill kills the bash immediately after the pkill command executes, and therefore subsequent commands do not have a chance to execute.
Apart from splitting the them into two lines:
bash -c 'pkill -TERM -f java'
bash -c 'true'
Is there any other workaround?
If you want to kill all java processes, simply drop the -f:
bash -c 'pkill -TERM java; true'
If you really also want to kill non-java processes like mplayer "jungle_gremlins_of_java.avi", the typical "solution" is to rewrite the command so that the pattern doesn't match itself:
bash -c 'pkill -TERM -f "[j]ava"; true'

terminate infinite loop initiated in remote server when exiting bash script

Script which executes commands in infinite loop in background
<SOMETHING ELSE AT START OF SCRIPT>
cmd='while true;
do
ps aux | head;
sleep 1;
done > $FILE'
ssh root#$SERVER $cmd &
...
...
<SOME OTHER TASKS>
...
...
( at the end of this script, how to kill the above snippet executing in remote server)
[ kindly note i dont want to wait as the while loop is infinite ]
Read and tried some posts from stackoverflow, but could not find exact solution for this problem.
Rather than an infinite loop, use a sentinel file:
cmd='while [ -r /tmp/somefile];
do
# stuff
done > $FILE'
ssh root#$SERVER touch /tmp/somefile
ssh root#$SERVER $cmd &
# do other stuff
ssh root#$SERVER rm -f /tmp/somefile
This follows your current practice of putting the remote command in a variable, but the arguments against that cited elsewhere should be considered.
If you want to kill the ssh process running in background at the end of your script, just do:
kill $!
I assume this is the only (or the last) process you started in background.
Try following sequence
CTRL+Z
fg
CTRL+C
or
jobs
kill %jobspec
To kill everything belonging to user logged in you could try:
whois=`w|grep $user|awk '{print $2}'`;user=root; ssh $user#server -C "ps auwx|grep $whois|awk '{print \$2}'"
This will list all the processes owned by the user you just logged in as - just add |xargs kill -9
whois=`w|grep $user|awk '{print $2}'`;user=root; ssh $user#server -C "ps auwx|grep $whois|awk '{print \$2}'|xargs kill -9 "
whois=`w|grep $user|awk '{print $2}'`;user=root; ssh $user#server -C "ps auwx|grep $whois|awk '{print \$2}'|awk '{print "kill -9 " $1}'|/bin/sh "

Resources