概要
类型
-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
。如果存在 header,它总是以 shebang
开始,可能后跟 comment
和 emu_args
。shebang
默认为 "/usr/bin/env escript"
。comment
默认为 "This is an -*- erlang -*- file"
。创建的 escript 可以作为二进制文件返回或写入文件。
作为如何使用此函数的示例,我们创建一个解释型的 escript,它使用 emu_args
来设置一些模拟器标志。在这种情况下,它恰好使用 +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"...>>}]}
可以如下创建一个没有 header 的 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 的上下文之外调用该函数,则行为是未定义的。