linux - How to kill a child process after a given timeout in Bash?

ID : 20144

viewed : 21

Tags : linuxbashunixlinux

Top 5 Answer for linux - How to kill a child process after a given timeout in Bash?

vote vote

92

(As seen in: BASH FAQ entry #68: "How do I run a command, and have it abort (timeout) after N seconds?")

If you don't mind downloading something, use timeout (sudo apt-get install timeout) and use it like: (most Systems have it already installed otherwise use sudo apt-get install coreutils)

timeout 10 ping www.goooooogle.com 

If you don't want to download something, do what timeout does internally:

( cmdpid=$BASHPID; (sleep 10; kill $cmdpid) & exec ping www.goooooogle.com ) 

In case that you want to do a timeout for longer bash code, use the second option as such:

( cmdpid=$BASHPID;      (sleep 10; kill $cmdpid) \    & while ! ping -w 1 www.goooooogle.com       do           echo crap;       done ) 
vote vote

89

# Spawn a child process: (dosmth) & pid=$! # in the background, sleep for 10 secs then kill that process (sleep 10 && kill -9 $pid) & 

or to get the exit codes as well:

# Spawn a child process: (dosmth) & pid=$! # in the background, sleep for 10 secs then kill that process (sleep 10 && kill -9 $pid) & waiter=$! # wait on our worker process and return the exitcode exitcode=$(wait $pid && echo $?) # kill the waiter subshell, if it still runs kill -9 $waiter 2>/dev/null # 0 if we killed the waiter, cause that means the process finished before the waiter finished_gracefully=$? 
vote vote

73

sleep 999& t=$! sleep 10 kill $t 
vote vote

61

I also had this question and found two more things very useful:

  1. The SECONDS variable in bash.
  2. The command "pgrep".

So I use something like this on the command line (OSX 10.9):

ping www.goooooogle.com & PING_PID=$(pgrep 'ping'); SECONDS=0; while pgrep -q 'ping'; do sleep 0.2; if [ $SECONDS = 10 ]; then kill $PING_PID; fi; done 

As this is a loop I included a "sleep 0.2" to keep the CPU cool. ;-)

(BTW: ping is a bad example anyway, you just would use the built-in "-t" (timeout) option.)

vote vote

50

Assuming you have (or can easily make) a pid file for tracking the child's pid, you could then create a script that checks the modtime of the pid file and kills/respawns the process as needed. Then just put the script in crontab to run at approximately the period you need.

Let me know if you need more details. If that doesn't sound like it'd suit your needs, what about upstart?

Top 3 video Explaining linux - How to kill a child process after a given timeout in Bash?

Related QUESTION?