shell script to kill tomcat service if it is not stopped by stop command after certain amount of time? - linux

I would like to write shell script to start and stop tomcat server.For stopping the tomcat I am using this command "./bin/shudown.sh" or "./bin/catalina.sh stop". This is not working most of the times, tomcat is still running.So I would like to kill the tomcat after giving shutdown command and wait for sometime(say 5min). Can anybody help me how to do it?

./bin/catalina.sh should support this. If you run that command without any options, it will print out its usage, which describes:
stop n -force Stop Catalina, wait up to n seconds and then use kill -KILL if still running
In order to make this work, you need to set the environment variable CATALINA_PID to a file name that will be used to hold the Tomcat process ID. To start Tomcat, use:
export CATALINA_PID=/tmp/catalina.pid
./bin/catalina.sh start
And then to stop it:
export CATALINA_PID=/tmp/catalina.pid
./bin/catalina.sh stop 600 -force
This will try to stop it, wait for 5 minutes, then kill it if necessary. Note that this will run in the foreground by default (locking up the terminal instance); use a trailing & to run the command in the background.

You can use: pkill -9 tomcatServiceName or killall -9 tomcatServiceName.

Related

How do I stop a scirpt running in the background in linux?

Let's say I have a silly script:
while true;do
touch ~/test_file
sleep 3
done
And I start the script into the background and leave the terminal:
chmod u+x silly_script.sh
./silly_script.sh &
exit
Is there a way for me to identify and stop that script now? The way I see it is, that every command is started in it's own process and I might be able to catch and kill one command like the 'sleep 3' but not the execution of the entire script, am I mistaken? I expected a process to appear with the scripts name, but it does not. If I start the script with 'source silly_script.sh' I can't find a process by the name of 'source'. Do I need to identify the instance of bash, that is executing the script? How would I do that?
EDIT: There have been a few creative solutions, but so far they require the PID of the script execution to be stored right away, or the bash session to not be left with ^D or exit. I understand, that this way of running scripts should maybe be avoided, but I find it hard to believe, that any low privilege user could, even by accident, start an annoying script into the background, that is for instance filling the drive with garbage files or repeatedly starting new instances of some software and even the admin has no other option, than to restart the server, because a simple script can hide it's identifier without even trying.
With the help of the fine people here I was able to derive the answer I needed:
It is true, that the script runs every command in it's own process, so for instance killing the sleep 3 command won't do anything to the script being run, but through a command like the sleep 3 you can find the bash instance running the script, by looking for the parent process:
So after doing the above, you can run ps axf to show all processes in a tree form. You will then find this section:
18660 ? S 0:00 /bin/bash
18696 ? S 0:00 \_ sleep 3
Now you have found the bash instance, that is running the script and can stop it: kill 18660
(Of course your PID will be different from mine)
The jobs command will show you all running background jobs.
You can kill background jobs by id using kill, e.g.:
$ sleep 9999 &
[1] 58730
$ jobs
[1]+ Running sleep 9999 &
$ kill %1
[1]+ Terminated sleep 9999
$ jobs
$
58730 is the PID of the backgrounded task, and 1 is the task id of it. In this case kill 58730 and kill %1` would have the same effect.
See the JOB CONTROL section of man bash for more info.
When you exit, the backgrounded job will get a kill signal and die (assuming that's how it handles the signal - in your simple example it is), unless you disown it first.
That kill will propogate to the sleep process, which may well ignore it and continue sleeping. If this is the case you'll still see it in ps -e output, but with a parent pid of 1 indicating its original parent no longer exists.
You can use ps -o ppid= <pid> to find the parent of a process, or pstree -ap to visualise the job hierarchy and find the parent visually.

Kill a "background process" in Linux using a C Program

I have started my process in background and I would like to kill that process using a C program using popen().
I have tried in many ways but in vain. The reason is when I run a C code, it is executed in a sub-shell because of which I can't get the processes running in main shell.
I used $! to get the latest pid running in the background, but because of the above reason it didn't work.
my_process & pids="${pids-} $!" //start my process
sleep 10 // run for 10 seconds
kill -2 $pids //kill the process
Also you can store PID in file and kill it.like
./process1.sh &
echo $! > /tmp/process1.pid
kill -9 `cat /tmp/process*.pid`
rm /tmp/process*.pid
You should make your process into a daemon, that way you can start, end and restart it without complications.
You can start here: Best way to make a shell script daemon?
+1 on Raydel's answer
Another alternative (since there are so many ways to do things) If you have root you can also create it as a service and then start it and stop it manually using the "service" commands.
(Sorry wanted to add as a comment to Raydel's but my rep is not high enough apparently so adding as a separate answer)

Why can't I start tomcat using catalina in a shell script

I'm curious of how su -c "cmd arg" and tomcat works within a shell script.
Manually from the cmd line, I ran:
su -m tomcat -c /path/to/tomcat/catalina.sh start
This didn't work. However, if I put the cmd in quotes, it worked
su -m tomcat -c "/path/catalina.sh start"
Within a shell script (trying to run chkconfig so it starts automatically), I have something like this:
START="/path/catalina.sh start"
...
...
su -m tomcat -c "$START"
The command is in quotes since I found out manually that quotes are required.
When I run the script, the output comes back as:
Using CATALINA_BASE: /apps/local/apache-tomcat-7.0.42
Using CATALINA_HOME: /apps/local/apache-tomcat-7.0.42
Using CATALINA_TMPDIR: /apps/local/apache-tomcat-7.0.42/temp
Using JRE_HOME: /usr/java/default
Using CLASSPATH: /apps/local/apache-tomcat-7.0.42/bin/bootstrap.jar:/apps/local/apache-tomcat-7.0.42/bin/tomcat-juli.jar
Usage: catalina.sh ( commands ... )
commands:
debug Start Catalina in a debugger
debug -security Debug Catalina with a security manager
jpda start Start Catalina under JPDA debugger
run Start Catalina in the current window
run -security Start in the current window with security manager
start Start Catalina in a separate window
start -security Start in a separate window with security manager
stop Stop Catalina, waiting up to 5 seconds for the process to end
stop n Stop Catalina, waiting up to n seconds for the process to end
stop -force Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running
stop n -force Stop Catalina, wait up to n seconds and then use kill -KILL if still running
configtest Run a basic syntax check on server.xml - check exit code for result
version What version of tomcat are you running?
Note: Waiting for the process to end and use of the -force option require that $CATALINA_PID is defined
This output is like if I manually ran catalina.sh w/o any start/stop arguments. Why is the start/stop option being ignored in the shell script? Yes, I replaced catalina.sh with startup.sh and shutdown.sh and that made the script work but I'm still curious why inside a script, su -c "cmd arg" seemed to ignore the argument portion of the command.
Thanks in advance for your explanation. I'll shoot myself if it's something as easy as shell expansion and quote removal unless I do something to make it not lose the quote.
I use the following in my tomcat init files:
...
su -l $TOMCAT_USER -c $CATALINA_HOME/bin/startup.sh
...
The -l creates a login shell and allows you to pass what you need.
This might be related also with "setenv.sh"
If you created setenv.sh, and have lines starts with "set X=Y", then you will get this problem, because of "set". Remove "set" and try to restart tomcat again.
https://ubuntuforums.org/showthread.php?t=2032330

Bash script on background: how to kill child processes

Well, I'm basically trying to make a bash script runs a node script forever. I made the following bash script:
#!/bin/bash
while true ; do
cd /myscope/
unlink nohup.out
node myscript.js
sleep 6
done & echo $! > pid
I'm expecting that when it runs, it starts up node with the given script, checks if node exits, sleeps for 6 seconds if so and reopen node. Also, I'm expecting it to run in background and writes it's pid (the bash pid) on a file called "pid".
Everything explained above works as expected, apparently, but I'm also expecting that when the pid of the bash script is killed, the node script would stop running, I don't know why that made sense in my mind, but when it comes to practice, it doesn't work. The bash script is killed indeed, but the node script keeps running and that is freaking me out.
I've tested it in the terminal, by not sending the bash script to the background and entering ctrl+c, both scripts gets killed.
I'm obviously miss understanding something on the way the background process works. For god sake, can anybody help me?
There are lots of tools that let you do what you're trying, just two off the top of my head:
https://github.com/nodejitsu/forever - A simple CLI tool for ensuring that a given script runs continuously (i.e. forever)
https://github.com/remy/nodemon - Monitor for any changes in your node.js application and automatically restart the server - perfect for development
Maybe the second it's not what you're looking for, but still worth a look.
If you can't or don't want to use those then the problem is that if you kill the parent process the child one is still there, so, you should kill that too:
pkill -TERM -P $PID
where $PID is the parent PID.

How to terminate screen while running a .sh?

I search everyplace but didn't find a solution to my question, please help!
My situation:
I need run a huge .sh in my AWS (amazon web service), it will take about 4-5 hours to finish the job, I don't want to sit down just look those logs, so I create a screen to run it (screen 1), but while I configure the installation, I make a stupid mistake to create another screen and config and execute (screen 2).
The question is:
Screen 2 finish the job and I 'exit' the screen(terminated), but I can't terminate screen 1, because when I enter 'exit', it become a parameter of configuration, CTRL+A+K also din't work, please tell me how can I kill this screen, thanks.
KILL -9 <pid> does the trick. If you want it to run in the background do it for the parent process.
logon to another session.
ps -ef | grep yourusername
will show you the processes running that you own. The leftmost number is the pid of the process.
Issue a kill command on the process you want to stop.
kill [pid]
If that fails try
kill -9 [pid]

Resources