我有一个脚本尝试使用另一个程序建立数据库连接,程序的超时(2.5分钟)很长。我想将此功能添加到脚本中。
如果连接时间超过5秒,则终止进程 否则就会杀死睡眠/杀戮过程。
我遇到的问题是bash在进程被杀死时如何报告,这是因为进程只在后台处于同一个shell中。有没有更好的方法来执行此操作或如何使shell为kill命令静音?
DB_CONNECTION_PROGRAM > $CONNECTFILE &
pid=$!
(sleep 5; kill $pid) &
sleep_pid=$!
wait $pid
# If the DB failed to connect after 5 seconds and was killed
status=$? #Kill returns 128+n (fatal error)
if [ $status -gt 128 ]; then
no_connection="ERROR: Timeout while trying to connect to $dbserver"
else # If it connected kill the sleep and any errors collect
kill $sleep_pid
no_connection=`sed -n '/^ERROR:/,$p' $CONNECTFILE`
fi
答案 0 :(得分:106)
有一个名为timeout的{GNU coreutils实用程序:http://www.gnu.org/s/coreutils/manual/html_node/timeout-invocation.html
如果您在平台上拥有它,则可以执行以下操作:
timeout 5 CONNECT_TO_DB
if [ $? -eq 124 ]; then
# Timeout occurred
else
# No hang
fi
答案 1 :(得分:10)
我不知道它是否相同但几年前我确实解决了类似的问题。但是我是一个程序员,而不是一个像Unix一样的系统管理员,所以请注意以下几点,因为我的Bash-fu可能不那么强......
基本上我做了fork,fork和fork:)
内存不足在找回我的旧代码(我惊人地每天都使用它)之后因为我的内存不够好,在Bash中它的工作方式有点像这样:
commandThatMayHang.sh 2 > /dev/null 2>&1 & (notice that last '&', we're forking)
MAYBE_HUNG_PID=$!
sleepAndMaybeKill.sh $MAYBE_HUNG_PID 2 > /dev/null 2>&1 & (we're forking again)
SLEEP_AND_MAYBE_KILL_PID=$!
wait $MAYBE_HUNG_PID > /dev/null 2>&1
if [ $? -eq 0 ]
# commandThatMayHand.sh did not hang, fine, no need to monitor it anymore
kill -9 $SLEEP_AND_MAYBE_KILL 2> /dev/null 2>&1
fi
其中 sleepAndMaybeKill.sh 会休眠所需的时间,然后杀死 commandThatMayHand.sh 。
所以基本上这两种情况是:
你的命令退出正常(在5秒超时或其他之前),所以等待在你的命令退出时立即停止(并杀死“杀手”,因为它不再需要了
命令锁定,杀手最终杀死命令
在任何情况下,您都可以保证在命令完成后立即成功,或者在超时后立即失败。
答案 2 :(得分:1)
我找到了这个bash脚本 timeout.sh 作者:Anthony Thyssen(his web)。看起来不错。
答案 3 :(得分:0)
您是否意味着如果进程仍未运行,您不希望打印错误消息?然后,您可以重定向stderr
:kill $pid 2>/dev/null
。
您还可以检查进程是否仍在运行:
if ps -p $pid >/dev/null; then kill $pid; fi
答案 4 :(得分:0)
您可以设置2小时后超时,然后以这种方式循环循环javaScriptThatStalls
100次
seq 100|xargs -II timeout $((2 * 60 * 60)) javaScriptThatStalls