web-dev-qa-db-ja.com

所定の時間内でのCronジョブとランダムな時間

PHPスクリプトを1日に20回、完全にランダムな時間に実行する必要があります。午前9時から午後11時の間だけ実行することも必要です。

Linuxでのcronジョブの作成に精通しています。

84
floatleft

探しているものを理解したら、実行時間をランダム化するbashスクリプトを実行するcronジョブを作成するなど、少し面倒なことをする必要があります。次のようなものです。

crontab:

0 9 * * * /path/to/bashscript

および/ path/to/bashscript内:

#!/bin/bash

maxdelay=$((14*60))  # 14 hours from 9am to 11pm, converted to minutes
for ((i=1; i<=20; i++)); do
    delay=$(($RANDOM%maxdelay)) # pick an independent random delay for each of the 20 runs
    (sleep $((delay*60)); /path/to/phpscript.php) & # background a subshell to wait, then run the php script
done

いくつかのメモ:このアプローチでは、午前9時に20個のバックグラウンドプロセスを起動し、それぞれがランダムな分数(最大14時間、つまり午後11時)待機してからphpスクリプトを起動し、終了します。また、(秒ではなく)ランダムな分数を使用するため、開始時間は可能な限りランダムではありません。ただし、$ RANDOMは最大32,767で、午前9時から午後11時までの間に50,400秒あります。秒をランダム化するのは少し複雑です。最後に、開始時刻はランダムであり、互いに独立しているため、スクリプトの2つ以上のインスタンスが同時に開始される可能性があります(ただし、あまりありそうにありません)。

30
Gordon Davisson

ええ、ええ、質問は1年以上経過していますが、何か役に立つものを追加できるかもしれません。

午前9時から午後11時の間、1日20回、ランダムなオフセットで何かをcronする方法は? 14時間を20実行時間で割っているので、これはcron内ではやや扱いにくいです。他の回答は、PHPスクリプトのbashラッパースクリプトを記述する必要があるため、あまり好きではありません。

ただし、午前8時30分から午後11時9分までの間に13倍にタイミングと周波数の制限を緩和する自由を許可する場合、これはトリックを行う可能性があり、すべてcrontabの範囲内で:

30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php

$ {RANDOM:3:2}は、他の人が上記で言及したbashの$ RANDOMを使用しますが、bash配列スライスを追加します。 bash変数は型指定されていないため、疑似ランダムな符号付き16ビット数は、10進数の5桁のうち最初の2桁に切り捨てられ、cronジョブを10分から99分遅らせるための簡潔な1行になります(ただし、 10から32)。

以下もあなたのために働くかもしれませんが、何らかの理由で「ランダムではない」ことがわかりました(おそらく、ベンフォードの法則は擬似乱数を変調することによって引き起こされます。ちょっと、私は知りません、私は数学を失望させました... bashで!):

30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php

Cron(少なくともLinux 'vixie-cron')はエスケープされていない '%'に遭遇すると行を終了するため、モジュラスを上記の '\%'としてレンダリングする必要があります。

たぶん、別の7時間の範囲で別の行を追加することで、残りの7つのスクリプト実行を取得できます。または、午前3時から午後11時まで実行するように制限を緩和します。

119
al-x

だから私は次を使用して午前1時から330時までの間にコマンドを実行しています

0 1 * * * Perl -le 'sleep Rand 9000' && *command goes here*

それは私のランダムなニーズに対応してきました。それは9000秒== 150分== 2.5時間です

53
Dave

Cronは_RANDOM_DELAY_変数を提供します。詳細については、crontab(5)を参照してください。

RANDOM_DELAY変数を使用すると、変数で指定された上限で、ランダムな分数だけジョブの起動を遅らせることができます。

これはanacronジョブでよく見られますが、crontabでも役立ちます。

細かい(分)粒度で実行するジョブと、粗いジョブがある場合は、これに注意する必要があります。

17
Micah Elliott

私が最初に考えたのは、20個のランダムにスケジュールされたジョブを起動する1つのcronジョブを作成することです。 atユーティリティ(http://unixhelp.ed.ac.uk/CGI/man-cgi?at)は、指定された時間にコマンドを実行するために使用されます。

6
klaus

私はsleep $(( 1$(date +%N) % 60 )) ; dostuffs(bash&shと互換性があります)を使用することになりました

接頭辞1は、日付+%Nのベース8以外の解釈を強制することです(例:00551454)

Crontabファイルで\%を使用して%をエスケープすることを忘れないでください

* * * * *  nobody  sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs 
5
131

_at -f [file] [timespec]_

または

_echo [command] | at [timespec]_

または

_at [timespec]_ ...およびscriptの録音のようなインタラクティブな仕様。

コマンド

実行時に、テキストはstdinまたは_-f [file]_で指定されたファイルで提供されます。

タイムスペック

_[timespec]_文法 です。次のようになります。

  • 4桁の整数としての24時間。 _0100_、_2359_、_1620_
  • _now + 10 minutes_
  • _2071-05-31 - 5 hours 12 minutes UTC_

タイムゾーンを明示的に指定している場合、timespecの 一部のバージョン は、オプションのタイムゾーン引数にUTCのみを許可する場合があります。

cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

やってみて...

echoを事前に保留し、_|_(パイプ)をエスケープすることで、bashの解析をテストできます。

echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

スケジュールされたジョブを表示するには、atqとジョブの内容(環境変数、セットアップ、およびコマンド/スクリプト)を_at -c [jobid]_とともに使用します。

注意

システムはcronの一部であり、対話型プロンプトは実際にシェルの現在の状態全体をキャプチャするため、絶対パスを指定せずにコマンドを実行できます。

1
mcint

crontabコマンドはbashではなくshで実行されるため、al-xのソリューションは私には機能しません。動作するのは:

30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
0
Wilbert

ここで方法をグーグルした人のために:

Anacron(Ubuntuデスクトップおよびラップトップ)を使用している場合は、編集できます

/etc/anacrontab

そして追加

RANDOM_DELAY=XX 

XXは、基本ジョブを遅延させる分数です。

Anacronはcronに似ていますが、コンピューターが24x7(ラップトップのように)であることを期待しておらず、システムがダウンしたために見逃したスクリプトを実行します。

0
Ganesh Krishnan