Help us understand the problem. What is going on with this article?

自作timeoutスクリプト

More than 1 year has passed since last update.

TL;DR

あるコマンドを一定時間で強制終了させたいときには、timeoutコマンドを使っていました。
ところが、なんとインストールされていない環境で作業することがあったので、
簡易タイムアウトスクリプトを自作しました。

参考:timeoutコマンド

ryotakata@ryotakata-ubuntu03:~/timeout$ timeout --help
使用法: timeout [OPTION] DURATION COMMAND [ARG]...
または: timeout [OPTION]
Start COMMAND, and kill it if still running after DURATION.

Mandatory arguments to long options are mandatory for short options too.
      --preserve-status
                 exit with the same status as COMMAND, even when the
                 command times out
      --foreground
                 When not running timeout directly from a shell prompt,
                 allow COMMAND to read from the TTY and receive TTY signals.
                 In this mode, children of COMMAND will not be timed out.
  -k, --kill-after=DURATION
                 also send a KILL signal if COMMAND is still running
                 this long after the initial signal was sent.
  -s, --signal=SIGNAL
                 specify the signal to be sent on timeout.
                 SIGNAL may be a name like 'HUP' or a number.
                 See 'kill -l' for a list of signals
      --help     この使い方を表示して終了する
      --version  バージョン情報を表示して終了する

自作したtimeoutスクリプト

#!/bin/bash

function main () {
    SCRIPT_PATH=$(cd $(dirname $0) && pwd)
    SCRIPT_NAME=$(basename $0)

    ###  5 sec 経過でタイムアウトする
    ### [1] timeout コマンドを使う##############################################
    # timeout 5 ./hoge.sh
    ### [2] 下記Step1/2を1 sec毎に実行する######################################
    # Step1: kill -0 ${TGT_PID} or ${TIM_PID}でprocessの死活(終了/実行中)を取得
    # Step2: ${TIM_PID}, ${TIM_PID}の終了をOR条件で判定、killする
    # ※  ${TGT_PID}: タイムアウト監視対象のPID
    # ※  ${TIM_PID}: タイマーのPID
    ./hoge.sh &
    TGT_PID=$!
    sleep 5 &
    TIM_PID=$!

    err_msg=$(
    echo "${SCRIPT_PATH}/${SCRIPT_NAME}: "
    echo "Process ${TGT_PID} will be killed by ${SCRIPT_NAME}."
    )

    while true; do
        kill -0 ${TGT_PID}
        if [ ! $? -eq 0 ]; then
            killtree ${TIM_PID} KILL
            exit
        fi
        kill -0 ${TIM_PID}
        if [ ! $? -eq 0 ]; then
            killtree ${TGT_PID} KILL
            echo ${err_msg}
            exit 1
        fi
        sleep 1
    done
    wait
    ###########################################################################
    exit
}


### kill all members of a process group
function killtree() {
    if [ $# -eq 0 -o $# -gt 2 ]; then
        echo "Usage: $(basename $0) <pid> [signal]"
        exit 1
    fi
    local _pid=$1
    local _sig=${2:-TERM}
    kill -stop ${_pid} # needed to stop quickly forking parent from producing child between child killing and parent killing
    for _child in $(ps -o pid --no-headers --ppid ${_pid}); do
        killtree ${_child} ${_sig}
    done
    kill -${_sig} ${_pid}
}

main

参考にした記事

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした