web-dev-qa-db-ja.com

毎分よりも頻繁にcronジョブを実行できますか?

Sleepコマンドなしで30秒ごとにcronジョブを実行することは可能ですか?

48
user15336

タスクを頻繁に実行する必要がある場合、cronは間違ったツールです。それほど頻繁にジョブを起動しないという事実は別として、ジョブの起動間隔よりも実行に時間がかかる場合、深刻な問題が発生する危険性もあります。デーモン化して永続的に実行するようにタスクを書き直し、必要に応じてcronから起動します(すでに実行されている場合は再起動しないことを確認しながら)。

38

Linuxコマンドの most creative misuseの候補:

Nohup watch -n 30 --precise yourprog >/dev/null &

yourprogが次の場合:

date +%M.%S.%N >> yourprog.out

その場合、yourprog.outは次のようになります。

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

かなり良いレベルの精度を示しています。

コマンドの各部分の説明は次のとおりです。

  • Nohup-これにより、それに続くコマンド(この場合はwatch)がターミナルの終了時に終了しなくなります。
  • watch -このプログラムはコマンドを繰り返し実行します。通常、watchがコマンドを実行するたびに、コマンドの最初の1画面分の出力が表示されます。
  • -n 30-コマンドを実行する間隔。この場合は30秒ごとです。
  • --precise-このオプションがない場合、watchはコマンドafter interval secondsを実行します。これを使用すると、コマンドの開始ごとに begins on可能であればインターバルが開始されます。このオプションが例で指定されていない場合、起動してコマンド(yourprog)を実行するのに時間がかかるため、時間は毎回30秒以上遅くなります。
  • yourprog-実行するwatchのプログラムまたはコマンドライン。コマンドラインにシェル固有の文字(スペースやセミコロンなど)が含まれている場合は、引用符で囲む必要があります。
  • >/dev/null-大なり記号は、watchによって実行されているコマンドの出力をファイル/dev/nullにリダイレクトします。そのファイルは、書き込まれたデータをすべて破棄します。これにより、出力が画面に書き込まれなくなります。または、Nohupが使用されているため、Nohup.outというファイルに出力が送信されなくなります。
  • &-watchコマンドはバックグラウンドで実行され、制御は端末または親プロセスに戻ります。

Nohup、出力のリダイレクト、および&バックグラウンド制御演算子はwatchに固有のものではないことに注意してください。

次に、yourprogスクリプトの例の説明を示します。

  • date-現在の日付または時刻、あるいはその両方を出力します。それらを設定することもできます。
  • +%M.%S.%N-dateが使用する出力形式を指定します。 %Mは現在の分、%Sは現在の秒、%Nは現在のナノ秒です。
  • >> yourprog.out-dateコマンドの出力をyourprog.outというファイルにリダイレクトします。 2つの「より大」を指定すると、以前の内容が上書きされるのではなく、呼び出しごとに出力がファイルに追加されます。

編集

おそらく悪用される可能性のある別の可能性があります(またはおそらくそれが正当な用途です)はsystemdタイマーです。

cronの代替としてのsystemd/Timers および cron vs systemd timers を参照してください。

すぐに例を掲載してみます。

Cronは1分ごとに起動するように設計されているため、ハッキングなしでそれを行うことはできません。

14
Balázs Pozsár
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

前のインスタンスがすでに実行されている場合にプログラムが終了するように、プログラムに何かを書き込むことを忘れないでください。

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

もちろん、これでも失敗する可能性は非常に小さいため、googleを検索して、環境に適用できるより良いソリューションを探してください。

13
ghoti

サードパーティのソフトウェアでこれを行うことができます。

私にとってうまくいったオプションは 頻繁にcron です

ミリ秒の精度が可能で、現在の実行が終了するまで次の実行を延期するオプションを提供します。

8
thatjuan

私はいくつかの懸念があります:

(1)システムがビジー状態になり、30秒の時点で正確に開始できないことがある場合、あるジョブを実行しているときに別のジョブがポップし、2つ(またはそれ以上)のジョブが同じことを行う可能性があります。事。スクリプトによっては、ここで重大な干渉が発生する場合があります。したがって、そのようなスクリプトでのコーディングには、特定のスクリプトの1つのインスタンスのみが同時に実行されるようにするためのコードが含まれている必要があります。

(2)スクリプトは、オーバーヘッドが大きくなり、必要以上にシステムリソースを消費する可能性があります。これは、他の多くのシステムアクティビティと競合している場合に当てはまります。

したがって、1人の投稿者が述べたように、この場合、追加のプロセスで実行されるデーモンを入れて、操作にとって非常に重要な場合に実行され続けるようにすることを真剣に検討します。

2
mdpc

このタスクのための私の最も簡単でお気に入りのソリューション:

cronエントリ:
* * * * * flock -w0 /path/to/script /path/to/script

脚本:
while true;do echo doing something; sleep 10s;done

怠惰な代替::)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

または

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

長所

  • flockコマンドを使用すると、複数のインスタンスによるスクリプトの同時実行を回避できます。ほとんどの場合、それは非常に重要です。
  • flockおよびwatchコマンドは、ほとんどのLinuxインストールで使用できます

短所

  • この種の「サービス」を停止するには、2つの手順が必要です
    • cronエントリをコメント化する
    • スクリプトまたはwatchコマンドを強制終了します
1
asvany

自分のスクリプト用か、それをラップできる場合の解決策:

  1. 開始時間を取得して覚えています。
  2. 後で触れるロックファイルが存在し、スクリプトが60秒間実行されていない場合は、1秒待ってからもう一度確認してください。 (例えば、while/sleep)*
  3. 60秒経過してもロックファイルがまだ存在する場合は、古いロックの警告で終了します。
  4. ロックファイルをタッチします。
  5. スクリプトが60秒間実行されていない間、希望のスリープ時間で実際のタスクをループします。
  6. ロックファイルを削除します。
  7. 細かくcronとして追加します。
  8. ボブはあなたの叔父です。

デーモンの構築と監視よりも頭痛の種は少ないです。

* PHPを使用している場合は、clearstatcache()を覚えておいてください。

0
Someone