shell中timeout实现

第一种

function timeout() {
waitsec=$SLEEP_TIME
( $* ) & pid=$!
( sleep $waitsec && kill -HUP $pid ) 2>/dev/null & watchdog=$!
# if command finished
if wait $pid 2>/dev/null; then
    pkill -HUP -P $watchdog
    wait $watchdog
fi
# else: command interrupted
}

第二种

function timeout()
{
    local time cmd pid

    if echo "$1" | grep -Eq '^[0-9]+'; then
        time=$1
        shift && cmd="$@"
    else
        time=5
        cmd="$@"
    fi

    $cmd &
    pid=$!

    while kill -0 $pid &>/dev/null; do
        sleep 1
        let time-=1

        if [ "$time" = "0" ]; then
            kill -9 $pid &>/dev/null
            wait $pid &>/dev/null
        fi
    done
}

假设有一个测试脚本sleep.sh:

$ cat sleep.sh
echo "sleep $1 seconds"
sleep $1
echo "awake from sleep"

现在利用我们写的timeout函数来达到超时kill功能:

$ time sh timeout.sh 2 'sh sleep.sh 100'
sleep 100 seconds

real    0m2.005s
user    0m0.002s
sys 0m0.001s

看最终执行的时间,差不多就是2秒钟。

上面timeout函数实现的代码中,利用了两个技巧:

  1. kill -0 $pid:发送信号0给进程,可以检查进程是否存活,如果进程不存在或者没有权限,则返回错误,错误码为1;
  2. wait $pid &>/dev/null:等待某个进程退出返回,这样相对比较优雅,同时将错误重定向到黑洞,从而隐藏后台进程被kill的错误输出;
posted @ 2017-01-05 15:27  苏小北1024  阅读(9669)  评论(0编辑  收藏  举报