摘要
型別
-type comment() :: string().
-type emu_args() :: string().
啟動時應傳遞給 erl 的任何引數。
-type extract_option() :: compile_source | {section, [section_name()]}.
-type section() :: shebang | {shebang, shebang() | default | undefined} | comment | {comment, comment() | default | undefined} | {emu_args, emu_args() | undefined} | {source, file:filename() | binary()} | {beam, file:filename() | binary()} | {archive, zip:filename() | binary()} | {archive, [zip_file()], [zip:create_option()]}.
-type section_name() :: shebang | comment | emu_args | body.
-type shebang() :: string().
初始的 #!
行。
例如
#!/usr/bin/env escript
-type zip_file() :: zip:filename() | {zip:filename(), binary()} | {zip:filename(), binary(), file:file_info()}.
函式
-spec create(file:filename() | binary(), [section()]) -> ok | {ok, binary()} | {error, term()}.
從區段清單建立 escript。
區段可以以任何順序指定。escript 以可選的 Header
開始,後接強制性的 Body
。如果標頭存在,則它始終以 shebang
開始,後面可能跟著 comment
和 emu_args
。shebang
預設為 "/usr/bin/env escript"
。comment
預設為 "This is an -*- erlang -*- file"
。建立的 escript 可以以二進制檔形式傳回或寫入檔案。
作為如何使用此函式的範例,我們建立一個使用 emu_args
設定一些模擬器標誌的直譯式 escript。在此範例中,它剛好使用 +S3
設定排程器的數量。我們也從新建立的腳本中提取不同的區段
> Source = "%% Demo\nmain(_Args) ->\n io:format(\"~p\",[erlang:system_info(schedulers)]).\n".
"%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(schedulers)).\n"
> io:format("~s\n", [Source]).
%% Demo
main(_Args) ->
io:format(erlang:system_info(schedulers)).
ok
> {ok, Bin} = escript:create(binary, [shebang, comment, {emu_args, "+S3"},
{source, list_to_binary(Source)}]).
{ok,<<"#!/usr/bin/env escript\n%% This is an -*- erlang -*- file\n%%!+S3"...>>}
> file:write_file("demo.escript", Bin).
ok
> os:cmd("escript demo.escript").
"3"
> escript:extract("demo.escript", []).
{ok,[{shebang,default}, {comment,default}, {emu_args,"+S3"},
{source,<<"%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(schedu"...>>}]}
可以如下建立沒有標頭的 escript
> file:write_file("demo.erl",
["%% demo.erl\n-module(demo).\n-export([main/1]).\n\n", Source]).
ok
> {ok, _, BeamCode} = compile:file("demo.erl", [binary, debug_info]).
{ok,demo,
<<70,79,82,49,0,0,2,208,66,69,65,77,65,116,111,109,0,0,0,
79,0,0,0,9,4,100,...>>}
> escript:create("demo.beam", [{beam, BeamCode}]).
ok
> escript:extract("demo.beam", []).
{ok,[{shebang,undefined}, {comment,undefined}, {emu_args,undefined},
{beam,<<70,79,82,49,0,0,3,68,66,69,65,77,65,116,
111,109,0,0,0,83,0,0,0,9,...>>}]}
> os:cmd("escript demo.beam").
"true"
在這裡,我們建立一個包含 Erlang 程式碼和 Beam 程式碼的封存腳本,然後我們迭代封存中的所有檔案並收集其內容以及關於它們的一些資訊
> {ok, SourceCode} = file:read_file("demo.erl").
{ok,<<"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...>>}
> escript:create("demo.escript",
[shebang,
{archive, [{"demo.erl", SourceCode},
{"demo.beam", BeamCode}], []}]).
ok
> {ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
{archive, ArchiveBin}]} = escript:extract("demo.escript", []).
{ok,[{shebang,default}, {comment,undefined}, {emu_args,undefined},
{{archive,<<80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
152,61,93,107,0,0,0,118,0,...>>}]}
> file:write_file("demo.zip", ArchiveBin).
ok
> zip:foldl(fun(N, I, B, A) -> [{N, I(), B()} | A] end, [], "demo.zip").
{ok,[{"demo.beam",
{file_info,748,regular,read_write,
{{2010,3,2},{0,59,22}},
{{2010,3,2},{0,59,22}},
{{2010,3,2},{0,59,22}},
54,1,0,0,0,0,0},
<<70,79,82,49,0,0,2,228,66,69,65,77,65,116,111,109,0,0,0,
83,0,0,...>>},
{"demo.erl",
{file_info,118,regular,read_write,
{{2010,3,2},{0,59,22}},
{{2010,3,2},{0,59,22}},
{{2010,3,2},{0,59,22}},
54,1,0,0,0,0,0},
<<"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...>>}]}
-spec extract(file:filename(), [extract_option()]) -> {ok, [section()]} | {error, term()}.
解析 escript 並提取其區段。這是 create/2
的反向操作。
即使區段不存在於 escript 中,也會傳回所有區段。如果特定區段恰好與預設值相同,則提取的值會設定為原子 default
。如果缺少區段,則提取的值會設定為原子 undefined
。
如果 escript 包含 source
程式碼,則選項 compile_source
只會影響結果。在此情況下,Erlang 程式碼會自動編譯,並傳回 {source, BeamCode}
而不是 {source, SourceCode}
。
範例
> escript:create("demo.escript",
[shebang, {archive, [{"demo.erl", SourceCode},
{"demo.beam", BeamCode}], []}]).
ok
> {ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
{archive, ArchiveBin}]} =
escript:extract("demo.escript", []).
{ok,[{{archive,<<80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
152,61,93,107,0,0,0,118,0,...>>}
{emu_args,undefined}]}
-spec script_name() -> string().
傳回所執行 escript 的名稱。
如果在 escript 的上下文之外呼叫此函式,則行為未定義。