Posted at

コマンドをキューイングできるTask Spoolerの紹介

More than 1 year has passed since last update.


概要

コマンドをキューイングする手段としてTask Spoolerを利用しました。


動機

次のような作業をする必要がありました。


  • コマンドを次々とシリアルに実行したい

  • どんなコマンドを実行する必要があるかは前もってわかっていない

  • 実行する必要のあるコマンドを自動的に得ることは難しく、自分が判断する必要があるので、対話的なターミナルに入力したい

  • コマンドの実行には長時間かかることがある

はじめのうちは「1つ実行している間に次のコマンドを用意して、実行中のコマンドが終了したら次のコマンドを入力する」ということを繰り返していましたが、次のコマンドを用意しても、今のコマンドが終了するまで待たされる場合があり「ターミナルからコマンドをキューイングして、デーモンに逐次実行してもらえないか」と考えました。


Task Spooler

公式サイトはこちらです。


task spooler is a Unix batch system where the tasks spooled run one after the other.


(公式サイトより引用)


導入

debian系では公式パッケージが配布されているのでaptで入れることができます。

sudo aptitude install task-spooler

ただしパッケージで配布されているのは0.7.5で、本稿執筆時点での最新は1.0.0であるため、気になる場合はソースから入れるのが良いと思います。

別途注意点として、公式サイトではバイナリはtsである前提で書かれています。一方パッケージの場合は名前がバッティングするので、tspとなっています。ソースからビルドするとどうなのかは確認していません。本稿ではtspで統一します。


基本

tspの後に実行するコマンドを渡すとキューに入ります。

for i in {0..9}; do

tsp sleep 1
done

キューに入ったときそのIDが出力されます。


出力

36

37
38
39
40
41
42
43
44
45

tspを引数なしで実行すると、キューを確認できます。


出力

ID   State      Output               E-Level  Times(r/u/s)   Command [run=1/1]

39 running /tmp/ts-out.zgaA0l sleep 1
40 queued (file) sleep 1
41 queued (file) sleep 1
42 queued (file) sleep 1
43 queued (file) sleep 1
44 queued (file) sleep 1
45 queued (file) sleep 1
36 finished /tmp/ts-out.jjqtva 0 1.00/0.00/0.00 sleep 1
37 finished /tmp/ts-out.xBrsZe 0 1.00/0.00/0.00 sleep 1
38 finished /tmp/ts-out.bjmRkh 0 1.00/0.00/0.00 sleep 1

このタイミングでは最初の3つが完了して1つが実行中、6つがキューに入っている状態です。


応用


標準入出力

tspに渡したコマンドの標準入出力はそのコマンドから切り離されます。標準出力・標準エラー出力は、デフォルトではコマンド(ID)ごとに別のファイルに書き出されます。tsp -c [id]とすることでその内容を表示できます。またファイル名はtspの出力のOutputカラムに載っていますし、tsp -o [id]で知ることもできます。

ちなみにIDを取るオプションは、IDを省略すると最後のコマンドのIDを指定したことになります。

リダイレクトしたい場合は、コマンドをsh -cに渡す形で記述する必要があります。Task Spoolerはシェルの構文を知らないからです。

tsp sh -c 'cat < input_file > output_file'


キューの使い分け

キューはunixドメインソケットにより区別されていて、パスはデフォルトでは$TMPDIR/socket-ts.$uidです。つまりユーザごとにキューがあるということです。

このパスはTS_SOCKET環境変数により変更することができます。これにより、同じユーザでもコマンドの種類によってキューを変えたり、逆にシステム全体で1つのキューを使ったりできます。

TS_SOCKET=/tmp/socket-ts.foo tsp ...


終わりに

本稿で触れていない機能もたくさんあるので、興味を持ったら公式サイトやTRICKSファイルを読んでください。


参考リンク

Task Spoolerを使ってみた