web-dev-qa-db-ja.com

crontabの$ RANDOMの問題

Cronの$ RANDOMに奇妙な問題があります。 cronjobが起動してからランダムにコマンドを実行したいと思います。

この例は端末で直接機能し、コマンドを最大30秒遅らせます(コマンドを必要なものに置き換えます。実際には/ dev/ttyUSB0へのエコーです)。

sleep `expr $RANDOM \% 30` ; command

同じ行がcrontabに配置されている場合、コマンドは常に遅延なしですぐに実行されます。

* * * * * sleep `expr $RANDOM \% 30` ; command

$ RANDOMのない式を使用すると、正常に機能します。これにより、15秒の遅延が発生します。

* * * * * sleep `expr 10 + 5` ; command

つまり、$ RANDOMはcronでは機能しないようです。

ただし、$ RANDOM自体がゼロと評価されるからというだけではありません。これにより、10の遅延が発生するはずだからです。

* * * * * sleep `expr $RANDOM \% 30 + 10` ; command

&& instreadof;も試してみましたしかし、それは役に立ちません。実際、コマンドはまったく実行されません。

もちろん、crontabから呼び出されるスクリプトに遅延を配置することもできますが、それは私の問題を説明せず、学習させません:-)

それが何か違いを生むなら、それはDebianLennyです。

9
marlar

cronは_/bin/sh_シェルを使用してタスクを実行します。一部のディストリビューションでは、これはdashへのシンボリックリンクです。どちらも、bash固有の拡張子である_$RANDOM_変数をサポートしていません。

  • Vixie-cronを使用すると、crontabの先頭に_Shell=/bin/bash_という行を配置できます。

  • それ以外の場合は、_bash -c 'echo $RANDOM'_またはPerl -e 'print int(Rand(65535))'で解決する必要があります。

    (上記の例では、65535が返される最大数です。スクリプト内で他の計算を適用することもできます。)

  • 適切に構成されたシステムでは、これについてはcron自体から通知されます。エラーメッセージを含むジョブ出力は、常に電子メールで送信されます。軽量MTAをインストールします。


また、bashでは、$(( ))が_`expr`_よりも優先されます。

17
user1686

cronは通常、「完全な」環境ではなく実行されます。つまり、同じ環境変数の多くを利用できないということです。どうやら$RANDOMはそのようなものの1つであり、実際、sleepコマンドは未定義の変数が原因でエラーで失敗しているだけです。そのため、&&ではなく;に切り替えたときにコマンドを実行できませんでした。 (実際には、$RANDOMはBash関数ですが、cronは完全なBash環境では実行されないため、明らかにこの関数がありません。)

このタスクを実行するには、前述のように、別のBashスクリプトを使用する必要があります。あるいは、cronコマンドでcat /dev/urandomを直接使用する方法を見つけることができるかもしれませんが、現在持っているものを別のBashスクリプトに移動するだけの方がおそらく簡単でしょう。

2
Kromey