頭の体操!

cron に 15 分置きに実行するようなジョブを設定する時、毎時 0, 15, 30, 45 分じゃなくて、微妙にずれた時間、例えば 3, 18, 33, 48 分を指定したい時があります。0 分スタートなら */15 という風に指定できますが、3 分スタートなら 3,18,33,48 と書かないといけないので若干面倒です。況して 5 分おきなど。

こういうちょっとした仕事はスクリプトを書いて解決しましょう!Perl (どんなディストリビューションでもデフォルトで入ってる…はず) で素直に書くとこんな感じでしょうか:

#!/usr/bin/perl

use 5.016;

my $step = shift @ARGV;
my $rand = int rand $step;

! $step || 60 % $step and die "60 が割り切れる数を指定してね!";
my $i;
for ($i = $rand; $i < 60 - $step; $i += $step) {
  print "$i,";
}
say $i;

コマンドライン引数に 15 を渡すと、こんなような出力が得られます: 9,24,39,54

何だかプログラミングの教本みたいです。ちょっと考え方を変えて、関数型言語みたいにリストありきで書いてみましょう:

#!/usr/bin/perl

use 5.016;

my $step = shift @ARGV;
my $rand = int rand $step;

! $step || 60 % $step and die "60 が割り切れる数を指定してね!";
say join ',', map {$_ * $step + $rand} (0..(int(60 / $step) - 1));

うまく動くとちょっと感動ものです。
が、Python や PHP は map を使うまでもなく range 関数で一発、という悲しい現実。

(コウヅ)