How to self-terminate a bash script after timeout?

39,161

Solution 1

If you always want the script to timeout after 5 minutes, you can simply use a block in a background process like this. If you use Ctrl+C while it's running, the background process will also terminate:

#!/bin/bash
{
    sleep 5m
    kill $$
} &

while true
do
    date
    sleep 1
done

Solution 2

The timeout utility that is a part of GNU coreutils does it for you:

timeout 5m bash script.sh

would terminate the script after 5 minutes of execution.

Solution 3

You get the PID with PID=$$.

What you want may be most easily achieved with the command timeout.

But you can run a background process, too:

(sleep $TIMEOUT && kill "$PID") &

Solution 4

You could change your loop to:

#!/bin/bash -
SECONDS=0
while ((SECONDS < 5*60))
do
  echo "line printed"
done

Or insert ((SECONDS < 5*60)) || exit within your deepest loop.

SECONDS in ksh, zsh and bash is a special variables that gets incremented every second.

Solution 5

You can use a check condition:

#!/bin/bash

START=$(date +%s)

while [[ $(($(date +%s) - $START)) -lt 300 ]]
do
    #do something here
done

echo QUIT

Explanation

  • date +%s get the time in seconds since epoch, we save it to START variable, mark start time of script.
  • [[ $(($(date +%s) - $START)) -lt 300 ]]: we get current time (date +%s again) subtract to start time (which is saved in START variable).
  • If the result is less than 300 (5 minutes), script continue running,
  • If the result is equal to or greater than 300, meaning script has run 5 minutes since start time, we quit the while loop, script ends.
Share:
39,161

Related videos on Youtube

MLSC
Author by

MLSC

Updated on September 18, 2022

Comments

  • MLSC
    MLSC over 1 year

    I have a bash script doing a lot of things called script.sh:

    #!/bin/bash
    #It
    #Is
    #Doing
    #Things
    

    Is there a way that I can get the process ID of this script from within itself, and then kill it after 5 minutes?

    Like:

    #!/bin/bash
    #Get pid of script.sh here, start a 5 minute timer and kill the script after time runs out
    #It
    #Is
    #Doing
    #Things
    
    • n.st
      n.st almost 10 years
    • Lesto
      Lesto almost 10 years
      uset timeout, redirect output to a file (maybe in /tmp, if it is on ram you get better performance) and tail -f that file.
  • MLSC
    MLSC almost 10 years
    Pardon but there is a problem..while my script is running it shows me output..but in your case this is not do that..Imagin you have infinitive while loop that echo sth...when I do what you said it doesn't show me output and my machine hangs...
  • MLSC
    MLSC almost 10 years
    Pardon but there is a problem..while my script is running it shows me output..but in your case this is not do that..Imagin you have infinitive while loop that echo sth...when I do what you said it doesn't show me output and my machine hangs...
  • MLSC
    MLSC almost 10 years
    Thank you..My script has infinitive loop...if I put my whole script into your while loop do you think it works? Thank you
  • cuonglm
    cuonglm almost 10 years
    I think you must use my while loop instead of your infinitive loop to make it works. Can you give more details about your script?
  • MLSC
    MLSC almost 10 years
    +1 This is my script
  • Hauke Laging
    Hauke Laging almost 10 years
    @MortezaLSC I have given you two suggestions. What exactly have you done?
  • MLSC
    MLSC almost 10 years
    see Gnouc's answer, This is my script and please see my update as well..Thank you very much
  • MLSC
    MLSC almost 10 years
    You see...It brings my script to background...while my script is running it shows sth in terminal runtime..
  • Darkhogg
    Darkhogg almost 10 years
    I think you still need to add & at the end to actually send it to the background. The brackets only start a subshell.
  • MLSC
    MLSC almost 10 years
    I think your answer is one of the best one..but I would be thankful and your answer would be accepted if you help me, This is my script . Where should I put your aswer here? Thank you very much
  • user
    user almost 10 years
    Works fine for me. I made a script consisting mostly of while : ; do echo hello ; done then ran timeout 1s bash ./thatscript.sh -- it printed "hello" a large number of times and terminated after about a second, as expected.
  • MLSC
    MLSC almost 10 years
    Your answer is the sth like Gnouc's answer and both are correct really...but in my case I confused...doesn't work
  • MLSC
    MLSC almost 10 years
    Your answer is the sth like Stephane Chazelas's answer and both are correct really...but in my case I confused...doesn't work
  • MLSC
    MLSC almost 10 years
    Thank you..this is a good answer but doesn't work in my case
  • Davide Norbiato
    Davide Norbiato almost 10 years
    ...Well, why not?
  • MLSC
    MLSC almost 10 years
    Owww...I saw your edited answer now...This is working absolutely...Thank you very much...
  • MLSC
    MLSC almost 10 years
    No..I put the whole script into your while loop with #!/bin/bash - and doesn't work as well...please see blujay's answer.. It is working well
  • MLSC
    MLSC almost 10 years
    I tested it and My system broke down :), I don't know why!!!
  • devnull
    devnull almost 10 years
    @MortezaLSC I'm not sure what happens in your case. This is a pretty standard utility designed for the very purpose.
  • MLSC
    MLSC almost 10 years
    Thank you very much @devnull . I used your answer and of course it is helping me...Thank you very much
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy about 7 years
    Didn't know such variable existed. As always, learned something new from your answers
  • django
    django over 3 years
    If you check via ps command , parent script and sleep are still running. Not recommended
  • Davide Norbiato
    Davide Norbiato over 3 years
    @django It works as-described for me. Run the script, Ctrl+C, run ps, and the background sleep process is terminated.