How to Kill a Process on No Output for Some Period of Time

How to kill a process on no output for some period of time

As far as I know, there isn't a standard utility to do it, but a good start for a one-liner would be:

timeout=10; if [ -z "`find output.log -newermt @$[$(date +%s)-${timeout}]`" ]; then killall -TERM application; fi

At least, this will avoid the tedious part of coding a more complex script.

Some hints:

  • Using the find utility to compare the last modification date of the output.log file against a time reference.
  • The time reference is returned by date utility as the current time in seconds (+%s) since EPOCH (1970-01-01 UTC).
  • Using bash $[] operation to subtract the $timeout value (10 seconds on the example)
  • If no output is returned from the above find, then the file wasn't changed for more than 10 seconds. This will trigger a true in the if condition and the killall command will be executed.

You can also set an alias for that, using:

alias kill_application='timeout=10; if [ -z "`find output.log -newermt @$[$(date +%s)-${timeout}]`" ]; then killall -TERM application; fi';

And then use it whenever you want by just issuing the command kill_application

If you want to automatically restart the application without human intervention, you can install a crontab entry to run every minute or so and also issue the application restart command after the killall (Probably you may also want to change the -TERM to -KILL, just in case the application becomes unresponsive to handleable signals).

Run a process and kill it if it doesn't end within one hour

The subprocess module will be your friend. Start the process to get a Popen object, then pass it to a function like this. Note that this only raises exception on timeout. If desired you can catch the exception and call the kill() method on the Popen process. (kill is new in Python 2.6, btw)

import time

def wait_timeout(proc, seconds):
"""Wait for a process to finish, or raise exception after timeout"""
start = time.time()
end = start + seconds
interval = min(seconds / 1000.0, .25)

while True:
result = proc.poll()
if result is not None:
return result
if time.time() >= end:
raise RuntimeError("Process timed out")
time.sleep(interval)

Kill process after a given time bash?

I don't know if it's identical but I did fix a similar issue a few years ago. However I'm a programmer, not a Unix-like sysadmin so take the following with a grain of salt because my Bash-fu may not be that strong...

Basically I did fork, fork and fork : )

Out of memory After founding back my old code (which I amazingly still use daily) because my memory wasn't good enough, in Bash it worked a bit like this:

commandThatMayHang.sh 2 > /dev/null 2>&1 &    # notice that last '&', we're forking
MAYBE_HUNG_PID=$!
sleepAndMaybeKill.sh $MAYBE_HUNG_PID 2 > /dev/null 2>&1 & # we're forking again
SLEEP_AND_MAYBE_KILL_PID=$!
wait $MAYBE_HUNG_PID > /dev/null 2>&1
if [ $? -eq 0 ]
# commandThatMayHand.sh did not hang, fine, no need to monitor it anymore
kill -9 $SLEEP_AND_MAYBE_KILL 2> /dev/null 2>&1
fi

where sleepAndMaybeKill.sh sleeps the amount of time you want and then kills commandThatMayHand.sh.

So basically the two scenario are:

  1. your command exits fine (before your 5 seconds timeout or whatever) and so the wait stop as soon as your command exits fine (and kills the "killer" because it's not needed anymore

  2. the command locks up, the killer ends up killing the command

In any case you're guaranteed to either succeed as soon as the command is done or to fail after the timeout.

How to kill subprocess if no activity in stdout/stderr

Try using signal.alarm to set a timer after each line is received, and then handle SIGALRM by checking if too much time has passed since the last line.

java killing process after a period of time

It will be a little tricky because once you terminate the process, its output is no longer available, so you have to grab the output before you kill it.

Thread.sleep(1000); 
InputStream in = proc.getInputStream();
byte[] data = new byte[in.available()];
in.read(data);
proc.destroy();

This is assuming that the process doesn't close itself in the meantime. If it does, the InputStream will not be available for use, and you'll wish you had been reading the data instead of twiddling your thumbs.

You'll definitely want to make this exception-safe — put the call to proc.destroy in a finally handler to ensure that the child process gets terminated.

Shell script to kill a process in specific time with process name and time as input

  • With this script you can kill the running process at a specific time by giving the process name and the time.

    [Note: The input for time must be in seconds only, i.e 120 for 2 minutes]
#!/bin/bash

LOG=/tmp/kill.log
EXIT_ON_KILL=true
read -p 'Process: ' name
read -p 'killat: ' time

PID=$(ps -ef | grep $name | awk '{print $2}')
ps -ef | grep $name | awk '{print $2}' &>>$LOG

if [ $? -eq 0 ]; then
echo -e "\n The process details "
ps -p $PID
else
echo -e "\nInvalid Process Name"
fi

current=$(date +"%T")
killat=$(date -d "+"$time" seconds" "+%T")
echo -e "\nCurrent time $current \nThe time target is $killat"

while :
do
current=$(date +"%T")
echo $current

if [ "${killat}" == "${current}" ]
then
kill -9 $PID &>>$LOG
if [ $? -eq 0 ]; then
echo "Process $name have been successfully killed"
if [ $EXIT_ON_KILL == true ];then
exit 0
fi
else
echo -e "\nFailed to Kill process $name"
echo -e "\nMay be Invalid Process Name"
exit 1
fi

fi
sleep 2
done

Sample Input:

Process: xxxx
Killat: 120

Find and kill a process in one line using bash and regex

In bash, you should be able to do:

kill $(ps aux | grep '[p]ython csp_build.py' | awk '{print $2}')

Details on its workings are as follows:

  • The ps gives you the list of all the processes.
  • The grep filters that based on your search string, [p] is a trick to stop you picking up the actual grep process itself.
  • The awk just gives you the second field of each line, which is the PID.
  • The $(x) construct means to execute x then take its output and put it on the command line. The output of that ps pipeline inside that construct above is the list of process IDs so you end up with a command like kill 1234 1122 7654.

Here's a transcript showing it in action:

pax> sleep 3600 &
[1] 2225
pax> sleep 3600 &
[2] 2226
pax> sleep 3600 &
[3] 2227
pax> sleep 3600 &
[4] 2228
pax> sleep 3600 &
[5] 2229
pax> kill $(ps aux | grep '[s]leep' | awk '{print $2}')
[5]+ Terminated sleep 3600
[1] Terminated sleep 3600
[2] Terminated sleep 3600
[3]- Terminated sleep 3600
[4]+ Terminated sleep 3600

and you can see it terminating all the sleepers.


Explaining the grep '[p]ython csp_build.py' bit in a bit more detail:

When you do sleep 3600 & followed by ps -ef | grep sleep, you tend to get two processes with sleep in it, the sleep 3600 and the grep sleep (because they both have sleep in them, that's not rocket science).

However, ps -ef | grep '[s]leep' won't create a process with sleep in it, it instead creates grep '[s]leep' and here's the tricky bit: the grep doesn't find it because it's looking for the regular expression "any character from the character class [s] (which is s) followed by leep.

In other words, it's looking for sleep but the grep process is grep '[s]leep' which doesn't have sleep in it.

When I was shown this (by someone here on SO), I immediately started using it because

  • it's one less process than adding | grep -v grep; and
  • it's elegant and sneaky, a rare combination :-)

Linux - how does the kill -k switch work in timeout command

The option -k is to send KILL signal after the specified seconds if the process couldn't be terminated after the timeout.

timeout first sends the TERM signal. If -k is specified, then it'll also send KILL signal, following the real timeout value.

For example

timeout -k 5 10 someCommand

timeout sends TERM signal after the 10 seconds. If someCommand didn't respond to TERM (e.g. it could block the TERM signal) then timeout sends KILL signal after 5 more seconds (i.e. at the 15th second since the start of execution). The signal KILL can't be blocked.



Related Topics



Leave a reply



Submit