指定された時間内のCronジョブとランダムな時間


99

PHPスクリプトを1日に20回完全にランダムな時間に実行する機能が必要です。また、午前9時から午後11時の間にのみ実行されるようにします。

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


1
質問はあまりよく提起されていません。最終的に、午前9時から午前11時までの時間軸で20ポイントを配分したいとします。しかし、最小時間差には制約がありますか?午前9時から午前10時30分の間は何もできませんか?これを容認できる唯一の方法は、クラウスのアイデアに思えます。09:00に20回選択することで、あらゆる制約を満たし、「at」でスケジュールを設定できます。
David Tonhofer 2013年

回答:


37

あなたが探しているものを理解している場合は、実行時間をランダム化する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つ以上のインスタンスが同時に開始される可能性があります(あまり可能性は高くありません)。


2
ドル記号をドロップし、二重括弧を左に移動することにより(例えば、((maxdelay = 14 * 60))または((delay = $RANDOM % maxdelay)))、算術代入を読みやすくすることができます。sleep引数には、まだ(必要であれば、あなたは、スペースを追加することもできますが)あなたはそれを持っている方法であることが必要です。
追って通知があるまで一時停止。

これも私にとってはうまくいきました。カスタムbashスクリプトは次のようになります sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Shyam Habarakada 2017年

私は何かを見落としているか、最大遅延をmaxdelay = $((14 *
60/20

@jenishSakhiya 20回の実行のそれぞれのランダムな遅延は絶対的なもので(まあ、午前9時に開始)、別の実行とは相対的ではありません。つまり、ランダムな遅延の1つが13時間になると、それは午後10時(午前9時の13時間後)に実行され、他の実行の13時間後ではありません。
Gordon Davisson、

138

ええ、ええ、質問は1年以上前ですが、多分私は何か便利なものを追加できます:

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

ただし、私が自由にタイミングと頻度の制限を午前8時30分から午後11時9分までの13倍に緩和することを許可すると、これはうまくいくかもしれません。

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

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

以下もうまくいくかもしれませんが、何らかの理由で「ランダム性が低い」ことがわかりました(おそらく、ベンフォードの法則は疑似乱数を変調することによって引き起こされます。 bashで!):

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

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

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


4
私は遅い答えが好きです。しかし、10から99の範囲で均等に分散されたランダムな整数を生成しようとしていて、RANDOMの出力が0から32,767である場合は、なぜそれを行わないのでしょう$[(RANDOM/368)+10]か。
jsdalton 2013年

3
@jsdalton:モジュロ演算子の方がいいと思いませんか?$((RANDOM % 90 + 10))テスト:for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
geon

5
それはbashismを避けるために、より良いかもしれないので、多くのシステムではcronが、デフォルトではbashを使用していません$RANDOMsleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m
pabouk

9
crontab使用bashする前に、が使用されていることを確認してください$RANDOMあなたが持っている場合vixie-cron(Ubuntuでは私のケースのようです)、あなたSHELL=/bin/bashはトップに追加することができます。ここには他のcronバージョンの代替手段があります:superuser.com/a/264541/260350
DaAwesomeP

1
上記の最初の提案を使用すると、crontab: errors in crontab file, can't install. Do you want to retry the same edit?助けて
いただけ

71

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

0 1 * * * perl -le 'sleep rand 9000' && *command goes here*

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


8
:: MindBLOWN :: perlを少し使用するための別のあいまいな場所。
Mark Carpenter Jr

これは間違いなく最も明確な答えです
Enrico Detoma

21

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

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

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

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


RANDOM_DELAY変数を使用したいのですが、Ubuntu 14.04.4 LTSのcrontab(5)のマンページでヒントを見つけることができません。
Exocom 2016年

それは残念です。そこではサポートされていないのでしょうか。Centos 7とArch Linuxのマンページに記載されています。
Micah Elliott

9
これは正解のようですが、例を挙げられますか?
ショビー

14
RANDOM_DELAY一度確立され、デーモンのランタイム全体で一定であることに注意してください。
Maciej Swic

5
このRANDOM_DELAYフラグはcronie-crondの機能ですが、Ubuntu vixie-cronはこのフラグのない実行中のようです。
クラビエツ

7

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


atの使用例は次のとおりです。stackoverflow.com
a

6

結局使用しましたsleep $(( 1$(date +%N) % 60 )) ; dostuffs(bash&shと互換性があります)

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

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

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

2
私のように誰かが疑問に思う場合:%Nは現在のnanosを提供しますが、一部のmanページにはそれに関する情報が不足しています。これは、コマンドごとに「ある程度のランダム性」を簡単に必要とする人々にとって非常に賢いソリューションです。
ThorstenSchöning2016年

他の場所ですでに説明されている警告を除いて、これはGNUを使用している場合にのみ機能しますdate(ほとんどのLinuxでは可能ですが、Busybox、標準のMacOS、または他のさまざまなBSD派生プラットフォームでは機能しません)。
tripleee

4

al-xのソリューションは私にとってはうまくいきません。crontabコマンドはbashでは実行されず、shでは実行されるためです。何が機能します:

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

私はすべてを試しましたが、それでもうまくいきませんでした。あなたは投稿、理由を説明しました、ありがとう!
marlar

$[ ... ]waaaayが戻って以来、非推奨の構文です。この千年紀からのものについては、どちら$((RANDOM\%90))mがPOSIX互換の構文であるかを好みます(もちろんRANDOM、まだBashのみです)。
3

1

at -f [file] [timespec]

または

echo [command] | at [timespec]

または

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

コマンド

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

タイムスペック

ここに[timespec] 文法があります。次のようになります。

  • 24時間対応の4桁の整数として時間、例えば010023591620
  • 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の一部であり、対話型プロンプトは実際にはシェルの現在の状態全体をキャプチャするため、絶対パスを指定せずにコマンドを実行できます。


0

ここで方法をググった人のために:

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

/etc/anacrontab

そして追加

RANDOM_DELAY=XX 

XXは、基本ジョブを遅らせたい分数です。

Anacronはcronに似ていますが、コンピューターが(ラップトップのように)24時間365日稼働することを想定しておらず、システムがダウンしているために見逃したスクリプトを実行します。


0

この例では、コマンドを実行する前にランダムな時間を使用することができます。

#!/bin/bash
# start time
date +"%H:%M:%S"

# sleep for 5 seconds
sleep $(shuf -i 1-25 -n 1)
# end time
date +"%H:%M:%S"

0

crontabを毎日書き換えるスクリプトを作成するのはどうですか?

  1. 現在のcronを読み取る(A)
  2. ランダムな時間を選ぶ(B)
  3. 以前のcronを書き換え(A)、新しいランダムcronを追加(B)
  4. 最初にこのスクリプトを実行するには、必ずcronに追加してください。

2
回答としてコメントを投稿して、評判システムを回避しないでください。しかし、あなたのコメントは実際は答えになるほど十分によく見えます。「コメントを追加するための担当者はいませんが削除することをお勧めします。
Ted Lyngmo

1
私はこの回答を確認したところ、最後に見返りに質問をしている部分を見逃しました(私の部分ではずさんな作業)。答えの質問をしないでください。あなたが持っている質問のためにあなた自身の質問を投稿してください。私はあなたの半問を答えが出るようなものにした。
Ted Lyngmo

1
とった!どうも。次回はもっと注意します。悪意はありませんでした。
メロフェロー

1
きっとあなたは悪意がなかったと思いますし、過度に注意する必要はありません。あなたは可能な解決策を概説しました-そして最後に少しつまずきました。心配ない!
Ted Lyngmo

0

私はそれが古いスレッドであることを理解していますが、私がよく使用するランダムな値に関連するものを1つ追加したいと思います。$ RANDOM変数を固定範囲と限定範囲で使用する代わりに、シェルで任意の範囲のランダムな値を作成することがよくあります。

dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none

たとえば、次のことができます

FULLRANDOM=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none)

そして、このスレッドで議論されたいくつかの制限を克服します。


1
SOへようこそ。さて、古いスレッドかどうかに関係なく、これは私に送信し~$info dd、私はの左側で何が起こっているのか理解できます|が、右側を理解できません。ですから、overcoming some restrictionsランダムな値の生成に興味がある私や他の人にとっては、RHSを説明するために少し時間を取って、あなたのアプローチを使用するためにより強力なピッチを作ってみませんか。説明の深さは、あなたが提案するプロセスとその利点のおかげで人々を快適にします。
クリス

ああ。od aka "octal dump"は、ファイルまたはstdinを取得し、人間が読める形式でバイナリデータをダンプします。数値を符号なし10進数として表示し(-t u4)、アドレスインデックスを使用しません(-A none)。-N4は4バイトしかとらないため冗長ですが、問題もありません。これで説明が
付く
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.