escript的高级特性
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: escript的高级特性
escript Erlang scripting support, 可以让erl模块转身变成unix script来使用,大大方便用户,具体的使用参看otp文档。我这里要演示的是些比较被忽视的高级特性:
首先crack erts/etc/common/escript.c:33 static int debug = 1; 让之显示调用参数。
root@nd-desktop:~# cat >factorial
[color=red]#!/usr/bin/env escript %% -*- erlang -*- %%! -smp enable -sname factorial -mnesia debug verbose[/color] 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).
CTRL+D
root@nd-desktop:~# chmod +x factorial root@nd-desktop:~# ./factorial 10
[color=red]erl +B -boot start_clean -noshell -smp enable -sname factorial -mnesia debug verbose -run escript start -extra ./factorial 10[/color]
factorial 10 = 3628800
特性1:
摘抄文档。。。
On the third line (or second line depending on the presence of the Emacs directive), it is possible to give arguments to the emulator, such as
%%! -smp enable -sname factorial -mnesia debug verbose
Such an argument line must start with %%! and the rest of the line will interpreted as arguments to the emulator.
我们可以看到 这些选项被传递给了 erl
特性2:
-mode(compile).
这个选项是在escript.erl这个模块处理的。默认情况下 escript是被解释执行的,如果你的脚本很复杂,那么效率估计会是瓶颈。这种情况下, 你可以通过这个选项来让escript来先编译你的模块成opcode, 在vm里面运行。
特性3:
-d 选项 用来调试script的
-c 编译执行
-i 解释执行
-s 只检查不执行
root@nd-desktop:~# escript -d ./factorial 10
我们就可以看到 调试界面如下图
特性4:
可以把一个beam文件作为script
root@nd-desktop:/usr/src# cat hello.erl
-module(hello). -export([start/0,main/1]). main(_)-> start(). start()-> io:format("hello world~n",[]).
root@nd-desktop:/usr/src# erlc hello.erl root@nd-desktop:/usr/src# cat >hello
#!/usr/bin/env escript %% -*- erlang -*- %%! -smp enable -sname factorial -mnesia debug verbose
CTRL+D
root@nd-desktop:/usr/src# cat hello.beam >>hello root@nd-desktop:/usr/src# chmod +x hello root@nd-desktop:/usr/src# ./hello hello world
特性5:
可以把一个zip文件作为script
root@nd-desktop:/usr/src# cat hello.erl
-module(hello). -export([start/0,main/1]). main(_)-> start(). start()-> io:format("hello world, fac(10)=~w ~n",[fac:fac(10)]).
root@nd-desktop:/usr/src# cat fac.erl
-module(fac). -export([fac/1]). fac(0) -> 1; fac(N) -> N * fac(N-1).
root@nd-desktop:/usr/src# erlc *.erl root@nd-desktop:/usr/src# erl Erlang R13B03 (erts-5.7.4) [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.7.4 (abort with ^G) 1> zip:zip("hello.zip", ["hello.beam", "fac.beam"]). {ok,"hello.zip"} 2>
root@nd-desktop:/usr/src# cat >hello
#!/usr/bin/env escript %% -*- erlang -*- %%! -smp enable -sname factorial -mnesia debug verbose -escript main hello
CTRL+D
root@nd-desktop:/usr/src# cat hello.zip >>hello root@nd-desktop:/usr/src# chmod +x hello root@nd-desktop:/usr/src# ./hello hello world, fac(10)=3628800
特性6:
在独立的包里面 把escript伪装成我们的应用程序
root@nd-desktop:/usr/src# cat >hello.escript
-module(hello). -export([start/0,main/1]). main(_)-> start(). start()-> io:format("hello world~n",[]).
CTRL+D
root@nd-desktop:/usr/src# cp `which escript` hello root@nd-desktop:/usr/src# ./hello hello world
规则是 escript 改名成xxxx 执行xxxx的时候 实际上要读取的脚本是 xxxx.escript
综述: escript是很强大的 未来的erlang standalone全靠它。
Post Footer automatically generated by wp-posturl plugin for wordpress.
好文章,了解了escript的很多特性,收藏啦!
恩 本来想写点 没想到花了好几个小时 把所有的东西都挖潜出来了 未来standalone就会从escript开始作为入口
echo “hello”|cat – filetoappend >> final.out
第一个factorial代码在命令行下跑提示”: No such file or directory”,用which escript又可以找到”/usr/local/bin/escript”,直接用/usr/bin/env escript factorial就可以。
-pa这个选项试了一下没有效果,是不支持吗?
genesislive Reply:
August 18th, 2014 at 7:50 pm
第一个提示找到原因了,脚本是在windows下编辑的,行尾的格式不支持。
第二个指定%%! -pa ./ebin -pa ./deps/*/ebin,运行的时候用code:get_path()只找到./ebin,第二个路径没有找到
Yu Feng Reply:
August 18th, 2014 at 10:15 pm
-pa 没有问题的,最好在linux下搞。
genesislive Reply:
August 18th, 2014 at 11:55 pm
ubuntu上试过-pa ./deps/*/ebin在escript里面是解析不到路径的。