Created
November 16, 2012 18:24
-
-
Save doubleotoo/4089648 to your computer and use it in GitHub Desktop.
Execute a shell command with a timeout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Execute a command with a timeout | |
# Author: | |
# http://www.pixelbeat.org/ | |
# Notes: | |
# Note there is a timeout command packaged with coreutils since v7.0 | |
# If the timeout occurs the exit status is 124. | |
# There is an asynchronous (and buggy) equivalent of this | |
# script packaged with bash (under /usr/share/doc/ in my distro), | |
# which I only noticed after writing this. | |
# I noticed later again that there is a C equivalent of this packaged | |
# with satan by Wietse Venema, and copied to forensics by Dan Farmer. | |
# Changes: | |
# V1.0, Nov 3 2006, Initial release | |
# V1.1, Nov 20 2007, Brad Greenlee <brad@footle.org> | |
# Make more portable by using the 'CHLD' | |
# signal spec rather than 17. | |
# V1.3, Oct 29 2009, Ján Sáreník <jasan@x31.com> | |
# Even though this runs under dash,ksh etc. | |
# it doesn't actually timeout. So enforce bash for now. | |
# Also change exit on timeout from 128 to 124 | |
# to match coreutils. | |
# V2.0, Oct 30 2009, Ján Sáreník <jasan@x31.com> | |
# Rewritten to cover compatibility with other | |
# Bourne shell implementations (pdksh, dash) | |
if [ "$#" -lt "2" ]; then | |
echo "Usage: `basename $0` timeout_in_seconds command" >&2 | |
echo "Example: `basename $0` 2 sleep 3 || echo timeout" >&2 | |
exit 1 | |
fi | |
cleanup() | |
{ | |
trap - ALRM #reset handler to default | |
kill -ALRM $a 2>/dev/null #stop timer subshell if running | |
kill $! 2>/dev/null && #kill last job | |
exit 124 #exit with 124 if it was running | |
} | |
watchit() | |
{ | |
trap "cleanup" ALRM | |
sleep $1& wait | |
kill -ALRM $$ | |
} | |
watchit $1& a=$! #start the timeout | |
shift #first param was timeout for sleep | |
trap "cleanup" ALRM INT #cleanup after timeout | |
"$@"& wait $!; RET=$? #start the job wait for it and save its return value | |
kill -ALRM $a #send ALRM signal to watchit | |
wait $a #wait for watchit to finish cleanup | |
exit $RET #return the value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment