PIONEチュートリアル
'PIONEチュートリアル ここでは、PIONEのチュートリアルを行います。
基本1(特定のファイルを出力する)
まず、PIONEを動かすにはルール定義書をつくる必要があります。 どんな言語でも最初に作成するHelloプログラムを作ってみましょう。この場合、出力ファイルをひとつ指定することになります。
次の内容のファイル'HelloWorld.pione'を作成してみましょう。
Rule Main output 'message.txt' Action echo "Hello PIONE world !" > message.txt End
この後、pione-clientを実行します。
$ pione-client HelloWorld.pione -o helloOutput
例えば、次のような出力が流れます。
==> &Anonymous:Root([],{}) --> Rule Application: &Anonymous:Root([],{}) --> Distribution: &Anonymous:Root([],{}) >>> &Anonymous:Main([],{}) ==> &Anonymous:Main([],{}) SH ------------------------------------------------------------ SH echo "Hello PIONE world !" > message.txt SH ------------------------------------------------------------ <== &Anonymous:Main([],{}) <-- Distribution: &Anonymous:Root([],{}) <-- Rule Application: &Anonymous:Root([],{}) <== &Anonymous:Root([],{})
その結果、helloOutputというディレクトリができます。その中に指定したファイルmessage.txtが出力されています。
$ cat helloOutput/message.txt
Hello PIONE world !
もう一度、実行すると今度は、実行の必要がないために次のようなものが出力されます。
==> &Anonymous:Root([],{}) --> Rule Application: &Anonymous:Root([],{}) <-- Rule Application: &Anonymous:Root([],{}) <== &Anonymous:Root([],{})
さっきと比べると、Main Ruleが動いていないことが分かります。
さて、改めて設定したファイルを眺めてみます。
まず、最初に呼び出されるルール(Main)が定義されています。
Rule Main
Mainは、C言語などと同様に特別な意味をもつルールです。
次に、出力ファイルが定義されています。
output 'message.txt'
ここに書かれたファイルが最終的に-oで指定されたディレクトリに出力として戻ってきます。 Action以降が実際に起動するプログラムになります。
Action echo "Hello PIONE world !" > message.txt
実際にはシェルスクリプトが動きますので、どんなものも実行が可能です。
- !/bin/csh
で始めれば、cshを使って記述することもできますし、スクリプト系の言語であれば自由に記述し、実行形式を実行出来ます。
最後に、RuleをEndで終了します。
End
これが、一番シンプルなルールの書き方です。入力ファイルがないので、出力ファイルがなければ作成し、あれば、作成しないという動作をします。必要以上の動作をしないところが通常のシェルスクリプトを実行する場合と異なる展です。
基本2(特定のファイルを入力し、出力する(更新判定))
次に、入力ファイルから出力ファイルを作成する場合の定義書について作成してみましょう。
#Multiplying.pione Rule Main input 'test.in' output 'test.out' Action awk '{ print $1*2 }' {$I[1]} > {$O[1]} End
今回は、test.inという入力ファイルからその積算をして、test.outというファイルを作り出すルールです。入寮ファイルの更新判定により、ルールを実行するかどうかが変わってきます。
awkの使い方については、別途勉強してみて下さい。ここではファイルの中にある行頭の数字を2倍して、出力することができます。
まず、
$ mkdir MultiplyingInput $ pione-client Multiplying.pione -o MultiplyingOutput -i MultiplyingInput/
として、入力ファイルがあるディレクトリ(指定しなければ、現在のディレクトリ)を指定して実行してみます。
==> &Anonymous:Root([],{}) --> Rule Application: &Anonymous:Root([],{}) <-- Rule Application: &Anonymous:Root([],{}) <== &Anonymous:Root([],{})
入力ファイルがありませんので、何もする事がないとして終了してしまいます。先ほどとの違いに気がついたでしょうか。
次に、ファイルを作成して、実行してみます。
$ echo "3" > MultiplyingInput/test.in $ echo "5" >> MultiplyingInput/test.in $ cat MultiplyingInput/test.in 3 5 $ pione-client Multiplying.pione -o MultiplyingOutput -i MultiplyingInput/ ==> &Anonymous:Root([test.in],{}) --> Rule Application: &Anonymous:Root([test.in],{}) --> Distribution: &Anonymous:Root([test.in],{}) >>> &Anonymous:Main([test.in],{}) ==> &Anonymous:Main([test.in],{}) SH ------------------------------------------------------------ SH awk '{ print $1*2 }' {$I[1]} > {$O[1]} SH ------------------------------------------------------------ <-- Distribution: &Anonymous:Root([test.in],{}) <-- Rule Application: &Anonymous:Root([test.in],{}) <== &Anonymous:Main([test.in],{}) <== &Anonymous:Root([test.in],{}) $ cat MultiplyingOutput/test.out 6 10
となり、確かに2倍の値のファイルができあがっていることが分かります。 もう一度、実行すると、
$ pione-client Multiplying.pione -o MultiplyingOutput -i MultiplyingInput/ ==> &Anonymous:Root([test.in],{}) --> Rule Application: &Anonymous:Root([test.in],{}) <-- Rule Application: &Anonymous:Root([test.in],{}) <== &Anonymous:Root([test.in],{})
となり、ここでも何も実行しません。つまり、入力ファイルに比べて出力ファイルのほうが新しいので、更新判定の結果、実行しなくてよいと判断したことになります。賢いですね。
さて、ここで、ファイルを更新してみましょう。3行目に7を付け加えます。
$ echo "7" >> MultiplyingInput/test.in
そして、実行してみましょう。 $ pione-client Multiplying.pione -o MultiplyingOutput -i MultiplyingInput/
==> &Anonymous:Root([test.in],{}) --> Rule Application: &Anonymous:Root([test.in],{}) --> Distribution: &Anonymous:Root([test.in],{}) >>> &Anonymous:Main([test.in],{}) ==> &Anonymous:Main([test.in],{}) SH ------------------------------------------------------------ SH awk '{ print $1*2 }' {$I[1]} > {$O[1]} SH ------------------------------------------------------------ <-- Distribution: &Anonymous:Root([test.in],{}) <== &Anonymous:Main([test.in],{}) <-- Rule Application: &Anonymous:Root([test.in],{}) <== &Anonymous:Root([test.in],{}) $ cat MultiplyingOutput/test.out 6 10 14
今度は実行されました。これが更新判定によりルールが実行されるかどうかが判定されているということです。 もう一度実行しても、今度は実行されません。
$ pione-client Multiplying.pione -o MultiplyingOutput -i MultiplyingInput/ ==> &Anonymous:Root([test.in],{}) --> Rule Application: &Anonymous:Root([test.in],{}) <-- Rule Application: &Anonymous:Root([test.in],{}) <== &Anonymous:Root([test.in],{})
さて、出力ファイルを削除してみるとどうなるでしょうか。
$ rm MultiplyingOutput/test.out
今度は、実行されますね。
では、内容は変えずに、touch コマンドを使って、入力ファイルの修正時刻を変えるとどうなるでしょうか。 今回も、予想通り、動作しました。
もし、動作しないようだったら、バグです。すぐに、GITHUB/PIONEに報告しましょう。