4

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
  • 5
    mywiki.wooledge.org/XyProblem ;) – n.st May 18 '14 at 13:58
  • uset timeout, redirect output to a file (maybe in /tmp, if it is on ram you get better performance) and tail -f that file. – Lesto May 19 '14 at 9:17
3

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
  • Thank you..this is a good answer but doesn't work in my case – MLSC May 19 '14 at 12:55
  • 1
    ...Well, why not? – blujay May 19 '14 at 12:56
  • Owww...I saw your edited answer now...This is working absolutely...Thank you very much... – MLSC May 19 '14 at 13:00
14

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.

  • 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 May 18 '14 at 16:21
  • 2
    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. – a CVn May 19 '14 at 11:20
  • I tested it and My system broke down :), I don't know why!!! – MLSC May 19 '14 at 13:27
  • @MortezaLSC I'm not sure what happens in your case. This is a pretty standard utility designed for the very purpose. – devnull May 19 '14 at 13:30
  • Thank you very much @devnull . I used your answer and of course it is helping me...Thank you very much – MLSC May 19 '14 at 18:59
14

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") &
  • 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 May 18 '14 at 16:20
  • @MortezaLSC I have given you two suggestions. What exactly have you done? – Hauke Laging May 18 '14 at 19:25
  • see Gnouc's answer, This is my script and please see my update as well..Thank you very much – MLSC May 18 '14 at 19:30
  • You see...It brings my script to background...while my script is running it shows sth in terminal runtime.. – MLSC May 18 '14 at 19:32
  • 1
    I think you still need to add & at the end to actually send it to the background. The brackets only start a subshell. – Darkhogg May 18 '14 at 22:58
5

You could change your loop to:

#!/bin/bash -
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 holds the number of seconds since the shell started.

  • 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 – MLSC May 19 '14 at 11:18
  • Your answer is the sth like Gnouc's answer and both are correct really...but in my case I confused...doesn't work – MLSC May 19 '14 at 11:27
  • @MortezaLSC, your script is missing the #! /bin/bash - line so would be executed by sh. – Stéphane Chazelas May 19 '14 at 12:58
  • 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 May 19 '14 at 13:02
  • Didn't know such variable existed. As always, learned something new from your answers – Sergiy Kolodyazhnyy Mar 8 '17 at 23:25
4

You can use a check condition:

#!/bin/bash

START=$(date +%s)

while [[ $(($(date +%s) - $START)) -ne 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)) -ne 300 ]]: we get current time (date +%s again) subtract to start time (which is saved in START variable).
  • If the result is not equal 300 (5 minutes), script continue running,
  • If the result is equal 300, meaning script has run 5 minutes since start time, we quit the while loop, script ends.
  • Thank you..My script has infinitive loop...if I put my whole script into your while loop do you think it works? Thank you – MLSC May 18 '14 at 19:10
  • 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? – cuonglm May 18 '14 at 19:12
  • +1 This is my script – MLSC May 18 '14 at 19:15
  • 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 May 19 '14 at 11:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.