繰り返し実行を処理する防弾方法

繰り返し実行を処理する防弾方法

私のルーターには、30分ごとにcronによって実行されるスクリプトがあります。ルーターは時々数秒間隔で2回実行されますが、ルーターが起動したときにのみ実行されます。数週間前に同時に2回実行されるのを避けるために、pidofを使用して確認し、意図的にファイルロック方法を避けることで、可能な問題を回避しました。

for pid in $(pidof DoubleDDNS); do
  if [ $pid != $$ ]; then
    echo "DoubleDDNS [no2run] Exiting"
    exit 1
  fi
done

しかし。ちょうど問題が発生しました。何らかの理由でルーターが失敗しました。私の台本は明らかに終わらなかった。永遠に思い出に残る。したがって、上記の確認により、元の(以前の)実行がタスクを完了せずにスクリプトが再実行されるのを防ぎます。これは問題を引き起こします(新しいWAN IPアドレスはDDNSに報告されません)。

スクリプトを停止できるコマンドがないため、スクリプトの誤りとは思えません。このスクリプトは8ヶ月以上、複数のルータで問題なく実行されました。よく書かれており、可能なすべてのバグを処理してテストします。ルータはほとんどうまく動作しますが、その中の多くの部分が壊れています(SSLなど)。ルータは、3つのメモリ位置がいっぱいであることを報告しません(実際のものでもそうでない場合もあります)。私のWebGUIでリセットを選択してもリセットされず、オン/オフボタンを使用してリセットする必要があります!

それでは、私の小切手が2番目に実行されていることをどのように確認できますか?私の考えには、以前のインスタンスが60秒以上実行されていることを確認することも含まれます。

  1. 古いインスタンスをすべて終了してみてください。
  2. 反復実行にもかかわらず続きます。スクリプトは毎時3分と33分で実行され、単一の実行は15秒未満持続します。

質問(ファイルを生成しないことをお勧めしますが、ファイルロックを避けるのは悪い解決策である可能性があるため)

  1. 最後の実行時間を検出する方法は?
  2. 私よりも良いアイデアがありますか?
  3. スクリプトを終了する方法はありますか?スクリプトが60秒以内に完了しない場合は、このスクリプトインスタンスを終了してください。

覚えておいてください:ルーター、sh、ビジボックス。そのため、使用できるものは限られています。 ASUSルーターASUS RT-AC * UルーターはMerlinファームウェアで使用されます。

答え1

これは私が取り組んでいる防弾バージョンのモデルです。論理を示すために操作されたものです。私のルータではうまくいきます。

#!/bin/sh

age_max_sec=50

LOCKFILE=lock.txt
if [ -e ${LOCKFILE} ]; then
    echo "lockfile exists"
    if kill -0 `cat ${LOCKFILE}`; then
        echo "script runs in mem" 
        lock_date=`date -r ${LOCKFILE} +%s`
        now=`date +%s`
        lock_age=$(($now-$lock_date))
        if [ $lock_ag e -gt $age_max_sec ]; then
            echo "DoubleDDNS (no2runKILL)"
            kill `cat ${LOCKFILE}`
        else
            echo "DoubleDDNS (no2runOK), age $lock_age seconds, quit this run"
            exit 1
        fi   
    else
        echo "not allready running, go ahead"
    fi
fi

echo "working on"

# overkill???? just in case, scorched earth check.
filename=${0##*/}
for pid in $(pidof $filename); do
    if [ $pid != $$ ]; then
        echo "DoubleDDNS (no3runKILL)"
        kill -9 $pid
    fi
done

# make sure the lockfile is removed when we exit and then claim it
trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT
echo $$ > ${LOCKFILE}

# main program here

rm -f ${LOCKFILE}

echo "done"

最後の実行期間を確認するには、ロックファイルを使用する必要があるようです。したがって、pidを使用してロックファイルを作成します。ロックされたファイルが設定された秒制限よりも古い場合は終了します。古い場合は、古いインスタンスを終了します。私のルーターでこれを確認するより良い方法はありません。

初土検査をしなければなりませんか、それとも過度ですか?正当なロックファイルのスキャンが完了した後、メモリに残りますが、破損したプロセスがあるかどうかを再スキャンし、見つかった場合は終了します。問題は、最終的に実際の災害が再び発生し、定期的な清掃が失敗するまでテストする方法がないことです。致命的でなかったら…

NTPサービスの可用性は、タイムアウトロックと自殺薬に影響を与える可能性があることに注意してください。たとえば、上記のスクリプトを初めて実行すると、NTP回復時間の約4秒前に発生します。したがって、私たちはこれらのことを考慮する必要があります。

DopeGhotiが提供する上記の自殺薬は非常に効果的です。今、どの組み合わせを使用するかを決定する問題だけが残りました。それともみんな?ファイルロック、タイムアウト、超土化、自殺。まあ、それは過剰なように聞こえますが、それらのどれも互いに反対するのではなく、完璧な(編集的)調和で動作するようです。コメントを歓迎します。

関連情報