escript はコマンドライン引数から読み込んだ短い Erlangプログラムを最初にコンパイルすること無く実行する為の簡単な方法を提供します。
script-name script-arg1 script-arg2...
escript escript-flags script-name script-arg1 script-arg2...
escript は Erlang で書かれたスクリプトを実行します。
以下に例を示します。
$ cat factorial
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose
main([String]) ->
try
N = list_to_integer(String),
F = fac(N),
io:format("factorial ~w = ~w\n", [N,F])
catch
_:_ ->
usage()
end;
main(_) ->
usage().
usage() ->
io:format("usage: factorial integer\n"),
halt(1).
fac(0) -> 1;
fac(N) -> N * fac(N-1).
$ factorial 5
factorial 5 = 120
$ factorial
usage: factorial integer
$ factorial five
usage: factorial integer
Erlangスクリプトのヘッダーは通常の Erlangモジュールと異なります。最初の行は escript が呼び出す為のインタプリタ行です。しかしながらこんな風に escript を呼び出すことも出来ます
$ escript factorial 5
最初の行の内容は重要ではありませんが、Erlangのコードを含める事は出来ず、それは 無視 されるでしょう。
2行目は例えば EmacsエディタでErlangソースファイルを編集するために何のメジャーモードを使用するかの指示を任意で含みます。もしこの指示が存在する場合、それは2行目に位置しなければなりません。
3行目(あるいはEmacs指示の有無に応じて2行目になります)はエミュレータへ引数を渡すことが出来ます。こんな風に
%%! -smp enable -sname factorial -mnesia debug verbose
このような引数行は %%! で始まる必要があり、行の残りをエミュレータの引数として処理します。.
もしあなたが escript 実行ファイルの場所を知っている場合、最初の行に escript のパスを直接指定することが出来ます。 例えば:
#!/usr/local/bin/escript
他の種類のスクリプトと同様に、スクリプトファイルに実行ビットが無ければ、ErlangスクリプトはUNIXプラットフォームで動作しません。(chmod +x スクリプト名 を実行して実行ビットを有効にしてください。)
Erlangスクリプトファイルの残りの部分には Erlangソースコード、インライン beamファイル、インラインアーカイブファイルのいずれかを含めることが出来ます。
Erlangスクリプトは常にmain/1関数を含んでいなければなりません。スクリプトを実行すると、main/1関数はスクリプトに与えられた引数の文字列のリスト表現と共に呼び出されるでしょう(どんな変更や解釈も行われません)。
スクリプトのmain/1関数が正常に終了した場合、スクリプトの終了コードは 0 になります。もし実行中に例外が生成された場合、短いメッセージが表示され、スクリプトは終了コード 127 で終了します。
0以外の終了コードを返すには、halt(ExitCode)を呼び出してください; 例えば:
halt(1).
スクリプトのパス名を取得するには escript:script_name/0 を呼び出してください(このパス名は通常、絶対パスではありません)。
もしもファイルに(下記の例の様な)ソースコードを含んでいる場合、それはプリプロセッサの eppによって処理されます。これは(?MODULEの様な)定義済みマクロと同様に-include_libディレクティブの様なインクルードディレクティブも使用出来る事を意味します。例えば
-include_lib("kernel/include/file.hrl").
file:read_file_info/1関数によって使用されるレコードの為にレコード定義をインクルードします。
スクリプトは実行を開始する前に構文と意味の正当性を確認します。もし(未使用の変数などの)警告がある場合、それらは表示されて実行を続けます。もしエラーがある場合、それらは表示されてスクリプトは実行されずに終了コード 127 で終了します。
main/1関数のモジュール宣言とエクスポート宣言は任意です。
デフォルトで、スクリプトは逐次実行されます。しかし、以下の行スクリプトファイルに含める事によってあなたはコンパイルを強制する事が出来ます:
-mode(compile).
逐次解釈されたコードの実行はコンパイル済みコードの実行より遅くなります。コンパイルはそれ自体に少し時間が掛かってしまいますが、逐次解釈されたコードを何度も実行する場合にはコンパイルする価値が有るでしょう。
先に述べたように、スクリプトにはプリコンパイル済みの beamコードを含む事が出来ます。プリコンパイル済みスクリプトにおけるスクリプトヘッダの解釈はスクリプトにソースコードが含まれる場合とまったく同じです。 これはファイルに前記したような #! や %%! から始まる行を追記する事によって実行可能なbeamファイルを作成出来る事を意味します。 プリコンパイル済みスクリプトでは、main/1関数はエクスポートされている必要があります。
もう一つの選択肢はスクリプト内でErlangアーカイブ全体を持つことは出来ます。 アーカイブスクリプトにおけるスクリプトヘッダの解釈はスクリプトにソースコードが含まれる場合とまったく同じです。 これはファイルに前記したような #! や %%! から始まる行を追記する事によって実行可能なアーカイブファイルを作成出来る事を意味します。 アーカイブスクリプトでは、main/1関数はエクスポートされている必要があります。 デフォルトでモジュールとベース名が同じ escriptファイルの main/1関数が呼び出されます。 この挙動は、-escript main Moduleというようなエミュレータフラグを設定することで上書きすることが出来ます。 このModuleはエクスポートされたmain/1関数を持つモジュール名でなければなりません。 アーカイブとコードの読み込みに関するさらなる情報は code(3) を参照してください。
アーカイブファイルからコード読み込みは実験的です。準備が出来る前にリリースを行う唯一の目的は早期のフィードバックを得るためです。ファイルフォーマットや文法、インターフェースなどは将来のリリースで変更されるかもしれません。-escriptフラグもまた実験的です。