1 tsコマンドとは?
tsとはtask spoolerの略です。
コマンドをシリアライズに実行したいときに使うコマンドです。
たとえば、コマンドA、コマンドBを実行するとき、コマンドAの実行が完了したら
コマンドBを実行することができるようになります。
1つのターミナルで# command A && command B
と実行するのではありません。
2つのターミナルでそれぞれ、# command A
、# command B
を実行する場合に使用します。
なお、CentOSでは、本コマンドのパッケージがリポジトリに存在しないようです。
商用目的で使うには難しいかもしれません。
Ubuntuでは、下記manページで紹介されています。
http://manpages.ubuntu.com/manpages/eoan/man1/tsp.1.html
2 環境
VMware Workstation 14 Player上の仮想マシンを使いました。
仮想マシンのOS版数は以下のとりです。
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@server ~]# uname -r
3.10.0-957.el7.x86_64
3 コマンドのインストール
下記URLからts-1.0.tar.gz
をダウンロードします。
Red Hat GPGのようにファイルの信頼性が検証できないので、ちょっと不安ですが
個人利用の仮想マシンなのでインストールしてみました。
[root@server ~]# wget http://vicerveza.homeunix.net/~viric/soft/ts/ts-1.0.tar.gz
[root@server ~]# ls ts-1.0.tar.gz
ts-1.0.tar.gz
ダウンロードしたファイルを解凍します。
[root@server ~]# tar xvf ts-1.0.tar.gz
ts-1.0
ディレクトリに移動します。
[root@server ~]# cd ts-1.0/
[root@server ts-1.0]# ls
COPYING PORTABILITY buglist.bug env.c info.c main.c msgdump.c server_start.c testbench.sh
Changelog PROTOCOL client.c error.c jobs.c main.h mymail.sh setenv ts.1
Makefile README deb execute.c list.c makedeb print.c signals.c ttail.c
OBJECTIVES TRICKS debian-pkg gentoo mail.c msg.c server.c tail.c web
READMEにしたがって、make
コマンドを実行します。
[root@server ts-1.0]# make
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c main.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c server.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c server_start.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c client.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c msgdump.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c jobs.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c execute.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c msg.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c mail.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c error.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c signals.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c list.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c print.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c info.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c env.c
cc -pedantic -ansi -Wall -g -O0 -D_XOPEN_SOURCE=500 -D__STRICT_ANSI__ -c tail.c
cc -o ts main.o server.o server_start.o client.o msgdump.o jobs.o execute.o msg.o mail.o error.o signals.o list.o print.o info.o env.o tail.o
make install
を実行して、tsコマンドを/usr/local/bin
にインストールします。
[root@server ts-1.0]# make install
install -c -d /usr/local/bin
install -c ts /usr/local/bin
install -c -d /usr/local/share/man/man1
install -c -m 644 ts.1 /usr/local/share/man/man1
tsコマンドのインストール先ディレクトリを確認します。
/usr/local/bin/ts
にインストールされていることがわかります。
[root@server ts-1.0]# which ts
/usr/local/bin/ts
[root@server ts-1.0]# ts -V
Task Spooler v1.0 - a task queue system for the unix user.
Copyright (C) 2007-2016 Lluis Batlle i Rossell
4 オプション一覧
[root@server ~]# ts -h
usage: 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 finished jobs in the queue.
TS_MAXCONN maximum number of ts connections at once.
TS_ONFINISH binary called on job end (passes jobid, error, outfile, command).
TS_ENV command called on enqueue. Its output determines the job information.
TS_SAVELIST filename which will store the list, if the server dies.
TS_SLOTS amount of jobs which can run at once, read on server start.
TMPDIR directory where to place the output files and the default socket.
Actions:
-K kill the task spooler server
-C clear the list of finished jobs
-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 run if not specified.
-c [id] like -t, but shows all the lines. Last run if not specified.
-p [id] show the pid of the job. Last run if not specified.
-o [id] show the output file. Of last job run, if not specified.
-i [id] show job information. Of last job run, if not specified.
-s [id] show the job state. Of the last added, if not specified.
-r [id] remove a job. The last added, if not specified.
-w [id] wait for a job. The last added, if not specified.
-k [id] send SIGTERM to the job process group. The last run, if not specified.
-u [id] put that job first. The last added, if not specified.
-U <id-id> swap two jobs in the queue.
-B in case of full queue on the server, quit (2) instead of waiting.
-h show this help
-V show the program version
Options adding jobs:
-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 only if the job before ends well
-D <id> the job will be run only if the 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).
5 事前準備
tsコマンドの動作を確認するため、テスト用のスクリプトを作成します。
5.1 スクリプト作成
/var/log/messageにメッセージを出力するスクリプトを作成します。
PIDとシーケンス番号を1秒間隔で10秒間出力します。
[root@server ~]# cat tp.sh
# !/usr/bin/bash
NUM_MAX=10
i=0
while [ "$i" -lt ${NUM_MAX} ]
do
logger "$1 (PID=$$,NUM=$i)"
sleep 1
i=$((i+1))
done
[root@server ~]# chmod 744 tp.sh
5.2 スクリプトの動作確認
スクリプトが出力するログを確認するため、journalctlコマンドを実行します。
なお、journalctlコマンドの使い方は、ここ(journalctl コマンドの使い方)を参照してください。
[root@server ~]# journalctl -f
もう1つターミナルを開きます。
スクリプトは、引数にfirst
という文字列を指定して実行します。
[root@server ~]# ./tp.sh first
もう1つターミナルを開きます。
スクリプトは、引数にsecond
という文字列を指定して実行します。
[root@server ~]# ./tp.sh second
/var/log/messageを確認すると、最初に実行したスクリプトと、
次に実行したスクリプトの実行結果が入り混じっていることがわかります。
[root@server ~]# journalctl -f
10月 22 14:49:51 server root[5427]: first (PID=5426,NUM=0)
10月 22 14:49:52 server root[5429]: first (PID=5426,NUM=1)
10月 22 14:49:52 server root[5432]: second (PID=5431,NUM=0)
10月 22 14:49:53 server root[5434]: first (PID=5426,NUM=2)
10月 22 14:49:53 server root[5436]: second (PID=5431,NUM=1)
10月 22 14:49:54 server root[5438]: first (PID=5426,NUM=3)
10月 22 14:49:54 server root[5440]: second (PID=5431,NUM=2)
-以下、略-
tsコマンドを使うと、firstの出力が終わってから、secondの出力を開始できるようになります。
つまり、コマンドをシリアライズに実行することができるようになります。
6 ジョブ一覧を確認する方法(-l)
ジョブの一覧を確認してみます。
ジョブがなにも実行されていないことがわかります。
[root@server ~]# ts -l
ID State Output E-Level Times(r/u/s) Command [run=0/1]
7 ジョブをシリアライズに実行する方法
スクリプトが出力するログを確認するため、journalctlを実行します。
[root@server ~]# journalctl -f
もう1つターミナルを開きます。
引数にfirst
を指定してクリプトを実行します。以降、first
のジョブと呼びます。
ジョブのIDが0であることを示しています。
[root@server ~]# ts ./tp.sh first
0
引数にsecond
を指定してクリプトを実行します。以降、second
のジョブと呼びます。
ジョブのIDが1であることを示しています。
[root@server ~]# ts ./tp.sh second
1
ジョブ一覧を確認してみます。
firstのジョブはrunning
となっていて、実行中であることがわかります。
secondのジョブはqueued
となっていて、実行されるのを待っています。
[root@server ~]# ts -l
ID State Output E-Level Times(r/u/s) Command [run=1/1]
0 running /tmp/ts-out.Ihj37A ./tp.sh first
1 queued (file) ./tp.sh second
/var/log/messageを確認します。
first
のジョブの出力が終わってから、second
のジョブの出力が開始されています。
つまり、first
とsecond
はシリアライズに実行されていることがわかります。
[root@server ~]# journalctl -f
10月 22 14:52:07 server root[5480]: first (PID=5479,NUM=0)
10月 22 14:52:08 server root[5484]: first (PID=5479,NUM=1)
10月 22 14:52:09 server root[5486]: first (PID=5479,NUM=2)
10月 22 14:52:10 server root[5489]: first (PID=5479,NUM=3)
10月 22 14:52:11 server root[5491]: first (PID=5479,NUM=4)
10月 22 14:52:12 server root[5493]: first (PID=5479,NUM=5)
10月 22 14:52:13 server root[5495]: first (PID=5479,NUM=6)
10月 22 14:52:14 server root[5497]: first (PID=5479,NUM=7)
10月 22 14:52:15 server root[5499]: first (PID=5479,NUM=8)
10月 22 14:52:17 server root[5501]: first (PID=5479,NUM=9)
10月 22 14:52:18 server root[5504]: second (PID=5503,NUM=0)
10月 22 14:52:19 server root[5507]: second (PID=5503,NUM=1)
10月 22 14:52:20 server root[5509]: second (PID=5503,NUM=2)
10月 22 14:52:21 server root[5511]: second (PID=5503,NUM=3)
10月 22 14:52:22 server root[5514]: second (PID=5503,NUM=4)
10月 22 14:52:23 server root[5516]: second (PID=5503,NUM=5)
10月 22 14:52:24 server root[5518]: second (PID=5503,NUM=6)
10月 22 14:52:25 server root[5521]: second (PID=5503,NUM=7)
10月 22 14:52:26 server root[5523]: second (PID=5503,NUM=8)
10月 22 14:52:27 server root[5525]: second (PID=5503,NUM=9)
8 ジョブの状態を確認する方法(-s)
ジョブの状態を表示してみます。
first
のジョブ(ジョブID=0)は終了していることがわかります。
[root@server ~]# ts -s 0
finished
second
のジョブ(ジョブID=1)も終了していることがわかります。
[root@server ~]# ts -s 1
finished
9 ジョブの詳細情報を確認する方法(-i)
ジョブの詳細情報を表示してみます。
first
のジョブをキューに入れた時刻、実行時刻、終了時刻、実行時間が
表示されることがわかります。
[root@server ~]# ts -i 0
Exit status: died with exit code 0
Command: ./tp.sh first
Slots required: 1
Enqueue time: Tue Oct 22 14:52:07 2019
Start time: Tue Oct 22 14:52:07 2019
End time: Tue Oct 22 14:52:18 2019
Time run: 10.103129s
second
のジョブは、first
が終了したあとに実行されていることがわかります。
実行時間が約10秒であることがわかります。
[root@server ~]# ts -i 1
Exit status: died with exit code 0
Command: ./tp.sh second
Slots required: 1
Enqueue time: Tue Oct 22 14:52:08 2019
Start time: Tue Oct 22 14:52:18 2019
End time: Tue Oct 22 14:52:28 2019
Time run: 10.071855s
10 ジョブのPIDを確認する方法(-p)
first
のジョブのPIDが5479であることがわかります。
[root@server ~]# ts -p 0
5479
second
のジョブのPIDが5503であることがわかります。
[root@server ~]# ts -p 1
5503
11 ジョブの実行結果を保存しない方法(-n)
tsコマンドを実行すると、標準出力、標準エラーが/tmp配下に保存されます。
-n
を指定することで、標準出力、標準エラーが/tmp配下に保存されなくなります。
[root@server ~]# ls /tmp/ts-out.*
/tmp/ts-out.5bTNSj /tmp/ts-out.FI8k3S /tmp/ts-out.KvdsB5 /tmp/ts-out.T7y4HC /tmp/ts-out.mQCsbR
/tmp/ts-out.7ErZth /tmp/ts-out.FSxedU /tmp/ts-out.NenwCj /tmp/ts-out.VX9FX0 /tmp/ts-out.nirV9p
-n
オプションを指定してtsコマンドを実行します。
[root@server ~]# ts -n ./tp.sh first
[root@server ~]# ts -n ./tp.sh second
-n
オプションを指定すると、tsコマンドの実行結果が標準出力に出力されます。
[root@server ~]# ts -l
ID State Output E-Level Times(r/u/s) Command [run=0/1]
2 finished stdout 0 10.05/0.02/0.01 ./tp.sh first
3 finished stdout 0 10.06/0.01/0.02 ./tp.sh second
12 同時実行のジョブ数を変更する方法(-S)
ここでは、同時に実行可能なジョブ数を1(default)から2に変更してみます。
たとえば、ジョブA,ジョブB,ジョブCと実行したとき、
ジョブAとジョブBは同時(パラレル)に実行されますが、
ジョブCは、ジョブA,Bが終了したあとに実行されます。
12.1 同時に実行可能なジョブ数を確認する方法
同時に実行可能なジョブ数はデフォルトで1つです。
[root@server ~]# ts -S
1
12.2 同時に実行可能なジョブ数を変更する方法
[root@server ~]# ts -S 2
[root@server ~]# ts -S
2
first
,second
,third
の3つのジョブを同時に実行してみます。
[root@server ~]# ts -n ./tp.sh first; ts -n ./tp.sh second; ts -n ./tp.sh third
/var/log/messageを確認すると、途中までは、first
とsecond
がパラレルに
実行されていることがわかります。first
とsecond
が終了すると、third
の
実行が開始されていることがわかります。
[root@server ~]# journalctl -f
10月 22 16:20:04 server root[5875]: first (PID=5869,NUM=0)
10月 22 16:20:04 server root[5876]: second (PID=5873,NUM=0)
10月 22 16:20:05 server root[5879]: first (PID=5869,NUM=1)
10月 22 16:20:05 server root[5880]: second (PID=5873,NUM=1)
10月 22 16:20:06 server root[5884]: first (PID=5869,NUM=2)
10月 22 16:20:06 server root[5883]: second (PID=5873,NUM=2)
10月 22 16:20:07 server root[5888]: second (PID=5873,NUM=3)
10月 22 16:20:07 server root[5887]: first (PID=5869,NUM=3)
10月 22 16:20:08 server root[5891]: second (PID=5873,NUM=4)
10月 22 16:20:08 server root[5892]: first (PID=5869,NUM=4)
10月 22 16:20:09 server root[5895]: second (PID=5873,NUM=5)
10月 22 16:20:09 server root[5896]: first (PID=5869,NUM=5)
10月 22 16:20:10 server root[5900]: second (PID=5873,NUM=6)
10月 22 16:20:10 server root[5899]: first (PID=5869,NUM=6)
10月 22 16:20:11 server root[5903]: first (PID=5869,NUM=7)
10月 22 16:20:11 server root[5904]: second (PID=5873,NUM=7)
10月 22 16:20:12 server root[5907]: first (PID=5869,NUM=8)
10月 22 16:20:12 server root[5908]: second (PID=5873,NUM=8)
10月 22 16:20:13 server root[5912]: second (PID=5873,NUM=9)
10月 22 16:20:13 server root[5911]: first (PID=5869,NUM=9)
10月 22 16:20:14 server root[5916]: third (PID=5915,NUM=0)
10月 22 16:20:15 server root[5918]: third (PID=5915,NUM=1)
10月 22 16:20:16 server root[5920]: third (PID=5915,NUM=2)
10月 22 16:20:17 server root[5923]: third (PID=5915,NUM=3)
10月 22 16:20:18 server root[5925]: third (PID=5915,NUM=4)
10月 22 16:20:19 server root[5927]: third (PID=5915,NUM=5)
10月 22 16:20:20 server root[5929]: third (PID=5915,NUM=6)
10月 22 16:20:21 server root[5931]: third (PID=5915,NUM=7)
10月 22 16:20:22 server root[5933]: third (PID=5915,NUM=8)
10月 22 16:20:23 server root[5935]: third (PID=5915,NUM=9)
13 実行結果をクリアする方法(-C)
ジョブ一覧を確認します。
first
およびsecond
がfinished
の状態になっています。
つまり、実行が完了していることがわかります。
[root@server ~]# ts -l
ID State Output E-Level Times(r/u/s) Command [run=0/1]
0 finished /tmp/ts-out.FSxedU 0 10.05/0.01/0.02 ./tp.sh first
1 finished /tmp/ts-out.nirV9p 0 10.06/0.00/0.02 ./tp.sh second
ジョブの実行結果をクリアします。
実行結果がクリアされていることがわかります。
[root@server ~]# ts -C
[root@server ~]# ts -l
ID State Output E-Level Times(r/u/s) Command [run=0/1]
Z 参考情報
cron + α が欲しい時には ts(Task Spooler) のご利用をご検討下さいというメモ
時間のかかる複数のコマンドをキューに突っ込んで処理させる『Task Spooler』を試してみる
簡単なキュー登録による複数タスクのバッチ処理を可能にするTask Spooler
Queuing tasks for batch execution with Task Spooler