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的錯誤輸出;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM