綾小路龍之介の素人思考

[linux] 簡単なジョブスケジューラ

Linuxにはcronやatなどのジョブスケジューラがある。本気のスケジューラを導入するほどのものではないが、様々なコマンドを1時間毎に遅延実行させたいときに便利かな。ざっくりと検索したけど出てこなかったので、メモっておく。

まずは、atコマンドで次の日の深夜零時に実行するコマンドを登録する例。これと同じスキームで、様々なコマンドをキューイングして一時間おきに先入れ先出しで順番に実行するようにしたい。

$ echo -e 'hoge;\nfuga;' | at midnight

実行予定のコマンドはatで登録、登録時にコマンドの実行時刻を指定する部分を工夫する。新しいコマンドの登録時に登録済みのコマンド実行時刻を走査し、最も未来に実行するコマンドの実行時刻を見つけ、これに+1時間したものを新しいコマンドの実行時刻としてコマンドを登録。新しいコマンドの登録時に登録済みコマンドが見つからなければ次の日の0時を新しいコマンドの実行時刻としてコマンドを登録。以下の様なスクリプトとしてまとめてみた。基本的には上のat midnightの部分をsh delay_run.shに置換するだけで解決。

$ cat delay_run.sh
#!/bin/sh
# $ echo -e 'hoge;\nfuga;' | sh delay_run.sh
set -e -x
QUEUE=A
TIME=`at -l -q ${QUEUE} | sort -k6,6n -k3,3M -k4,4n -k5,5 | tail -n 1 | awk '{cmd = sprintf("date --date \"%s %s %s %s\" +\"%%s\"",$4,$3,$6,$5); cmd | getline t; close(cmd); print t;}'`
if [ "${TIME}" != "" ] ; then
    #num=`expr \( \( ${B} - ${A} \) / 3600 \) + 1`
    TIME=`expr ${TIME} + 3600`
else
    TIME=`date --date '1 day 0:00' +'%s'`
fi
TIME=`date --date @${TIME} +'%R %F'`
cat < /dev/stdin | at -q ${QUEUE} ${TIME}

実行管理はat任せなので、jobを入れ替えたいとか、順番を変えたいとかの場合はいちいち登録作業をやり直さなければいけないけれどね。

リファレンス

  1. Man page of AT
  2. Getting Yesterdays or Tomorrows Day With Bash Shell Date Command
  3. Man page of DATE
  4. Linux tip: Job scheduling with cron and at
  5. unixtime と 日付 の相互変換 - poohSec
  6. Man page of SORT
  7. Stray Penguin - Linux Memo (AWK)
  8. The GNU Awk User's Guide - 入力ファイルの読み込み
  9. シェルスクリプトで乱数を扱う - hyconの日記
  10. USP友の会:シェルスクリプトでの標準入力の読み方
  11. atq スケジュールされたジョブの一覧を表示する - UNIXコマンド辞典:CodeZine(コードジン)

ソーシャルブックマーク

  1. はてなブックマーク
  2. Google Bookmarks
  3. del.icio.us

ChangeLog

  1. Posted: 2010-08-22T01:45:45+09:00
  2. Modified: 2010-08-22T01:45:45+09:00
  3. Generated: 2017-04-14T23:09:17+09:00