30秒ごとにcronを実行する 質問する

30秒ごとにcronを実行する 質問する

さて、30 秒ごとに実行する必要がある cron があります。

私が持っているものは次のとおりです:

*/30 * * * * /bin/bash -l -c 'cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\'''

実行されていますが、これは 30 分ごとに実行されるのでしょうか、それとも 30 秒ごとに実行されるのでしょうか?

また、頻繁に実行する場合には cron は最適なツールではないかもしれないと読んだことがあります。Ubuntu 11.04 で使用またはインストールできる、より良いオプションとなる別のツールはありますか? 上記の cron を修正する方法はありますか?

ベストアンサー1

指定子があります*/30。これは、1 分ごとですが、30 刻み (つまり、30 分ごと) を意味します。1分未満の解像度にはならないため、別の方法を見つける必要があります。cron

1 つの可能性は、少々場当たり的ですが(a)、 2 つのジョブを用意し、1 つを 30 秒ずつずらすことです。

# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * *              /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )

簡単に同期できるようにコメントを追加してフォーマットしたことがわかります。

どちらのcronジョブも実際には 1 分ごとに実行されますが、後者のジョブはジョブの「本質」を実行する前に 30 秒待機します/path/to/executable

その他の( ベースcronではない)オプションについては、ここにある他の回答、特にfcronとについて言及している回答を参照してください。システムでこれらを使用できる場合( をインストールしているか、 を含むディストリビューションを持っているなど)systemdは、これらがおそらく望ましいでしょう。fcronsystemd


不完全なソリューションを使用したくない場合は、少し変更を加えたループベースのソリューションを使用できます。何らかの方法でプロセスを実行し続ける必要がありますが、それが解決すれば、次のスクリプトが機能するはずです。

#!/bin/env bash

# Debug code to start on minute boundary and to
# gradually increase maximum payload duration to
# see what happens when the payload exceeds 30 seconds.

((maxtime = 20))
while [[ "$(date +%S)" != "00" ]]; do true; done

while true; do
    # Start a background timer BEFORE the payload runs.

    sleep 30 &

    # Execute the payload, some random duration up to the limit.
    # Extra blank line if excess payload.

    ((delay = RANDOM % maxtime + 1))
    ((maxtime += 1))
    echo "$(date) Sleeping for ${delay} seconds (max ${maxtime})."
    [[ ${delay} -gt 30 ]] && echo
    sleep ${delay}

    # Wait for timer to finish before next cycle.

    wait
done

コツは、ペイロードが実行される前に、バックグラウンドsleep 30で開始することです。その後、ペイロードが終了したら、バックグラウンドが終了するまで待機します。sleep

ペイロードにn秒かかる場合 (ここでn <= 30)、ペイロード後の待機時間は 秒になります。 30 秒以上30 - nかかる場合、ペイロードが完了するまで次のサイクルは遅延されますが、それ以上は遅延されません。

出力を最初に簡単に追跡できるように、1 分間の境界で開始するデバッグ コードが含まれていることがわかります。また、最大ペイロード時間を徐々に増やして、最終的にペイロードが 30 秒のサイクル時間を超えるのを確認します (余分な空白行が出力されるので、効果は明ら​​かです)。

サンプル実行は次のとおりです (通常、サイクルは前のサイクルの 30 秒後に開始されます)。

Tue May 26 20:56:00 AWST 2020 Sleeping for 9 seconds (max 21).
Tue May 26 20:56:30 AWST 2020 Sleeping for 19 seconds (max 22).
Tue May 26 20:57:00 AWST 2020 Sleeping for 9 seconds (max 23).
Tue May 26 20:57:30 AWST 2020 Sleeping for 7 seconds (max 24).
Tue May 26 20:58:00 AWST 2020 Sleeping for 2 seconds (max 25).
Tue May 26 20:58:30 AWST 2020 Sleeping for 8 seconds (max 26).
Tue May 26 20:59:00 AWST 2020 Sleeping for 20 seconds (max 27).
Tue May 26 20:59:30 AWST 2020 Sleeping for 25 seconds (max 28).
Tue May 26 21:00:00 AWST 2020 Sleeping for 5 seconds (max 29).
Tue May 26 21:00:30 AWST 2020 Sleeping for 6 seconds (max 30).
Tue May 26 21:01:00 AWST 2020 Sleeping for 27 seconds (max 31).
Tue May 26 21:01:30 AWST 2020 Sleeping for 25 seconds (max 32).
Tue May 26 21:02:00 AWST 2020 Sleeping for 15 seconds (max 33).
Tue May 26 21:02:30 AWST 2020 Sleeping for 10 seconds (max 34).
Tue May 26 21:03:00 AWST 2020 Sleeping for 5 seconds (max 35).
Tue May 26 21:03:30 AWST 2020 Sleeping for 35 seconds (max 36).

Tue May 26 21:04:05 AWST 2020 Sleeping for 2 seconds (max 37).
Tue May 26 21:04:35 AWST 2020 Sleeping for 20 seconds (max 38).
Tue May 26 21:05:05 AWST 2020 Sleeping for 22 seconds (max 39).
Tue May 26 21:05:35 AWST 2020 Sleeping for 18 seconds (max 40).
Tue May 26 21:06:05 AWST 2020 Sleeping for 33 seconds (max 41).

Tue May 26 21:06:38 AWST 2020 Sleeping for 31 seconds (max 42).

Tue May 26 21:07:09 AWST 2020 Sleeping for 6 seconds (max 43).

不格好な解決策を避けたい場合は、おそらくこれがより良いでしょう。cronこのスクリプトが実行されているかどうかを定期的に検出し、実行されていない場合は開始するジョブ (または同等のもの) が依然として必要です。ただし、スクリプト自体がタイミングを処理します。


(a)私の同僚の中には、クラッジが私の得意技だと言う人もいます :-)

おすすめ記事