x時台に動くcronを調査する


cronって色々な書き方あるじゃないですか。5分間隔だと */5 * とか、毎時2分から5分間隔であれば 2-59/5 * とか、0時から6時・18時から23時の毎時0分だと 0 0-6,18-23 とか。短くスマートに書けるのはいいんですが、じゃあ「22時台に動いている処理は?」って言われると、ぱっと出てこないんですよね。grepしても出てこない。台帳作っとけよという話なんですが、なんというか…台帳をメンテするのも大変というか…台帳が信用おけないというか。

なので、cronの内容から「時」のフィールドを展開するワンライナーを考えてみました。かなり力技で。

メンテ等で影響するジョブを調査する上では「何時台に動いているバッチ」がわかればいいだろうと思うので、「時」のフィールドだけを対象にしています。

たとえばこんな感じのcronが登録されていたときに、

1
2
3
* */2       * * * echo a
* 3,6,12    * * * echo b
* 0-6,18-23 * * * echo c

以下のawkのワンライナーを通せばこんな感じで展開されます。カンマが前後についているのは、grep等で引っ掛けやすくするためです。

1
2
3
4
$ crontab -l | awk 'NF>5{gsub("*","0-23",$2);split($2,a1,",");for(i in a1){s=1;split(a1[i],a2,"/");if(2 in a2)s=a2[2]-0;if(a2[1]~/-/){split(a2[1],a3,"-");for(j=(a3[1]-0);j<=(a3[2]-0);j=j+s){printf ","j}}else{printf ","a2[1]}}printf ",";for(i=6;i<=NF;i++){printf(" %s",$i)}printf "\n"}'
,0,2,4,6,8,10,12,14,16,18,20,22, echo a
,3,6,12, echo b
,0,1,2,3,4,5,6,18,19,20,21,22,23, echo c

このawkをフォーマットしたものが以下です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# スケジュールフォーマットの場合
NF > 5 {
  # アスタリスクは0-23にする
  gsub("*", "0-23", $2);
  # カンマで分割してループ
  split($2, a1, ",");
  for (i in a1) {
    # ステップ
    s = 1;
    split(a1[i], a2, "/");
    if (2 in a2) s = a2[2] - 0;
    
    # 範囲指定されている
    if (a2[1] ~ /-/) {
      split(a2[1], a3, "-");
      for (j = (a3[1] - 0); j <= (a3[2] - 0); j = j + s) {
        printf ","j
      }
    }
    # 範囲でない
    else {
      printf ","a2[1]
    }
  }
  # 最後にカンマを追加
  printf ",";
  
  # 実行コマンド
  for (i = 6; i <= NF; i++) {
    printf(" %s", $i);
  }
  printf "\n"
}

これをExcelに落とし込むと、こんな感じで表現できます。

Image from Gyazo

この例だと、以下の関数が入ってます。

まぁまぁいい感じじゃないですかね。このワンライナーをエイリアス登録しとけば便利かな。