Problem
As a result, I’d like to be able to start this process for a certain period of time and then kill it if it doesn’t return properly after that time.
Is there an easy and reliable way to accomplish this with bash?
P.S. Please let me know if this is a better question for serverfault or superuser.
Asked by Greg
Solution #1
(See BASH FAQ #68, “How do I run a command and have it abort (timeout) after N seconds?”)
If you don’t mind waiting for something to download, install timeout (sudo apt-get install timeout) and use it as follows: (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 )
If you wish to do a timeout for a lengthier bash code, go with the second option:
( cmdpid=$BASHPID;
(sleep 10; kill $cmdpid) \
& while ! ping -w 1 www.goooooogle.com
do
echo crap;
done )
Answered by Ignacio Vazquez-Abrams
Solution #2
# Spawn a child process:
(dosmth) & pid=$!
# in the background, sleep for 10 secs then kill that process
(sleep 10 && kill -9 $pid) &
Alternatively, alternatively, to obtain the exit codes:
# 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=$?
Answered by Dan
Solution #3
sleep 999&
t=$!
sleep 10
kill $t
Answered by DigitalRoss
Solution #4
I had the same question and discovered two additional resources that were quite helpful:
So, on the command line (OSX 10.9), I use something like this:
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
Because this is a loop, I included a “sleep 0.2” to keep the CPU from overheating.
(By the way, ping is a horrible example; you’d just use the built-in “-t” (timeout) option instead.)
Answered by Ulrich
Solution #5
If you already have (or can easily construct) a pid file to track the child’s pid, you may write a script that checks the pid file’s modtime and kills/respawns the process as needed. Then just add the script to crontab and schedule it to execute at the time you require.
Let me know if you need more details. If that doesn’t sound like it’ll work for you, how about trying upstart?
Answered by kojiro
Post is based on https://stackoverflow.com/questions/5161193/how-to-kill-a-child-process-after-a-given-timeout-in-bash