おひさしブリーフ、かっぱです。
下図のように cron ジョブで定期的にスクリプトを生成して実行させようとした時、スクリプト完了する前に次の cron ジョブが走ってスクリプトが生成されて、そのスクリプトが実行されてしまうような状況に遭遇してどうしたもんかなと悩んでいたら ts というツールを見つけたので試してみた。

スクリプトやコマンドをts コマンド経由で実行することで、それらをジョブとしてキューに放り込んで順次実行してくれるツール。冒頭の構成にts を加えると下図のようになり、cron の開始時間とスクリプトの実行時間の依存関係は切り離される。

CentOS 6 に導入するにはソースコードを取得してビルドする必要がある。
$ cat /etc/redhat-releaseCentOS release 6.7(Final)$ sudo yum install gcc$ wget http://vicerveza.homeunix.net/~viric/soft/ts/ts-0.7.6.tar.gz$ tar zxvf ts-0.7.6.tar.gz$cd ts-0.7.6$ make$mkdir ~/bin$ cp ts ~/bin/ts
以下のような雑なシェルスクリプトを cron で実行させる。
$ cat demo.sh#!/bin/shDATE=`date +%s`echo"echo$DATE && sleep 300"> /tmp/test.sh.$DATE${HOME}/bin/ts logger-t ts_demo"スクリプトを作成しました"sleep3logger-t ts_demo"スクリプトを実行します"${HOME}/bin/ts sh /tmp/test.sh.$DATE${HOME}/bin/ts-d logger-t ts_demo"スクリプトの実行が完了しました"$ crontab-l*/3 * * * * /home/centos/demo.sh>/dev/null2>&1
暫く放置してからts コマンド(ts -l でも同等)を実行すると以下のようにts コマンド経由で実行したコマンド(スクリプト)がジョブとしてキューイングされている。
$ tsID State Output E-Level Times(r/u/s) Command[run=1/1]0 running /tmp/ts-out.b5xJat sh /tmp/test.sh.14704703261 queued(file)[0]&& logger-t ts_demo スクリプトの実行が完了しました2 queued(file) logger-t ts_demo スクリプトを作成しました3 queued(file) sh /tmp/test.sh.14704703424 queued(file)[3]&& logger-t ts_demo スクリプトの実行が完了しました
さらに暫く放置してからジョブ一覧を確認すると...
$ ts-lID State Output E-Level Times(r/u/s) Command[run=1/1]6 running /tmp/ts-out.FSSSnL sh /tmp/test.sh.14704705817 queued(file)[6]&& logger-t ts_demo スクリプトの実行が完了しました8 queued(file) logger-t ts_demo スクリプトを作成しました9 queued(file) sh /tmp/test.sh.147047076110 queued(file)[9]&& logger-t ts_demo スクリプトの実行が完了しました11 queued(file) logger-t ts_demo スクリプトを作成しました12 queued(file) sh /tmp/test.sh.147047094113 queued(file)[12]&& logger-t ts_demo スクリプトの実行が完了しました14 queued(file) logger-t ts_demo スクリプトを作成しました15 queued(file) sh /tmp/test.sh.147047112116 queued(file)[15]&& logger-t ts_demo スクリプトの実行が完了しました0 finished /tmp/ts-out.b5xJat0 300.00/0.00/0.00 sh /tmp/test.sh.14704703261 finished /tmp/ts-out.js0Oq60 0.00/0.00/0.00[0]&& logger-t ts_demo スクリプトの実行が完了しました2 finished /tmp/ts-out.6Jjrf60 0.00/0.00/0.00 logger-t ts_demo スクリプトを作成しました3 finished /tmp/ts-out.fotDb60 300.00/0.00/0.00 sh /tmp/test.sh.14704703424 finished /tmp/ts-out.8y6fdL0 0.00/0.00/0.00[3]&& logger-t ts_demo スクリプトの実行が完了しました5 finished /tmp/ts-out.lMTR8K0 0.00/0.00/0.00 logger-t ts_demo スクリプトを作成しました
finished となっているのは完了したジョブ。logger で吐いているログを見ると...
$ sudotail-f /var/log/messagesAug608:03:04 ip-xxx-xx-xx-xx ts_demo: スクリプトを実行しますAug608:03:49 ip-xxx-xx-xx-xx ts_demo: スクリプトの実行が完了しましたAug608:03:49 ip-xxx-xx-xx-xx ts_demo: スクリプトを作成しましたAug608:06:04 ip-xxx-xx-xx-xx ts_demo: スクリプトを実行しますAug608:08:49 ip-xxx-xx-xx-xx ts_demo: スクリプトの実行が完了しましたAug608:08:49 ip-xxx-xx-xx-xx ts_demo: スクリプトを作成しましたAug608:09:04 ip-xxx-xx-xx-xx ts_demo: スクリプトを実行しますAug608:12:04 ip-xxx-xx-xx-xx ts_demo: スクリプトを実行しますAug608:13:49 ip-xxx-xx-xx-xx ts_demo: スクリプトの実行が完了しましたAug608:13:49 ip-xxx-xx-xx-xx ts_demo: スクリプトを作成しました
以下は ts の主な操作。
$ ts-l$ ts-C$ ts-K以下のように-d オプションをつけてジョブを登録することで、${command-1} が正常終了したら ${command-2} が実行される。
$ ts ${command-1}$ ts -d ${command-2}$ ts-t${JOB_ID}
その他、以下がts のヘルプ。
$ ts-husage: ts[action][-ngfmdE][-L<lab>][-D<id>][cmd...]Env vars: TS_SOCKET the path to the unix socket used by the ts command. TS_MAILTO where to mail the result(on -m). Local user by default. TS_MAXFINISHED maximum finishedjobsin the queue. TS_MAXCONN maximum number of ts connections at once. TS_ONFINISH binary called on job end(passes jobid, error, outfile,command). TS_ENVcommand called on enqueue. Its output determines the job information. TS_SAVELIST filename which will store the list,ifthe server dies. TS_SLOTS amount ofjobs which can run at once,read on server start.TMPDIR directory where to place the output files and the default socket.Actions:-Kkill the task spooler server-Cclear the list of finishedjobs-l show the job list(default action)-S[num] get/set the number of max simultaneous jobs of the server.-t[id]"tail -n 10 -f" the output of the job. Last runifnot specified.-c[id] like-t, but shows all the lines. Last runifnot specified.-p[id] show the pid of the job. Last runifnot specified.-o[id] show the output file. Of last job run,ifnot specified.-i[id] show job information. Of last job run,ifnot specified.-s[id] show the job state. Of the last added,ifnot specified.-r[id] remove a job. The last added,ifnot specified.-w[id]waitfor a job. The last added,ifnot specified.-k[id] send SIGTERM to the job process group. The last run,ifnot specified.-u[id] put that job first. The last added,ifnot specified.-U<id-id> swap twojobsin the queue.-Bincase of full queue on the server, quit(2) instead of waiting.-h show thishelp-V show the program versionOptions addingjobs:-n don't store the output of the command. -E Keep stderr apart, in a name like the output file, but adding'.e'. -g gzip the stored output (if not -n). -f don't fork into background.-m send the output by e-mail(uses sendmail).-d the job will be run onlyifthe job before ends well-D<id> the job will be run onlyifthe job of given id ends well.-L<lab> name this task with a label, to be distinguished on listing.-N<num> number of slots required by the job(1 default).
本当にすいません。
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。