1. ホーム
  2. ubuntu

[解決済み] 30秒ごとにcronを実行する

2022-03-25 01:22:06

質問

私は30秒ごとに実行する必要があるクーロンを持っています。

以下は、私が持っているものです。

*/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を修正する方法はありますか?

解決方法は?

あなたが持っているのは */30 の中に つまり、1分ごとに30回ずつ(言い換えれば30分ごと)という意味です。このため cron は、分単位まで分解できないので、別の方法を探す必要があります。

ちょっと面倒ですが、ひとつの可能性として (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分待ってからジョブのquot;meat"を実行します。 /path/to/executable .

その他(非 cron -をベースにした)オプションについては、ここの他の回答、特に fcronsystemd . お使いのシステムがこれらを使用する機能を持っているのであれば、おそらくこれらの方が望ましいでしょう(たとえば、インストール時に fcron または systemd を含む)。


もし、あなたが しない を使いたければ、ちょっとした修正でループベースの解決策を使うことができます。それでも、何らかの形でプロセスを走らせ続けることを管理しなければならないが、それが解決すれば、以下のスクリプトが動作するはずだ。

#!/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 - n 秒になります。もし より 30秒を超えると、次のサイクルはペイロードが終了するまで延期されるが、それ以上は延期されない。

最初は出力がわかりやすいように、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) 私の仕事仲間は、私の得意技だと言ってくれる人もいます :-)