escript - Erlang scripting support
Please see following description for synopsis
escript(1) User Commands escript(1)
NAME
escript - Erlang scripting support
DESCRIPTION
escript provides support for running short Erlang programs without hav-
ing to compile them first, and an easy way to retrieve the command-line
arguments.
It is possible to bundle escript(s) with an Erlang runtime system to
make it self-sufficient and relocatable. In such a standalone system,
the escript(s) should be located in the top bin directory of the stand-
alone system and given .escript as file extension. Further the (built-
in) escript program should be copied to the same directory and given
the script's original name (without the .escript extension). This will
enable use of the bundled Erlang runtime system.
The (built-in) escript program first determines which Erlang runtime
system to use and then starts it to execute your script. Usually the
runtime system is located in the same Erlang installation as the
escript program itself. But for standalone systems with one or more
escripts it may be the case that the escript program in your path actu-
ally starts the runtime system bundled with the escript. This is inten-
tional, and typically happens when the standalone system bin directory
is not in the execution path (as it may cause its erl program to over-
ride the desired one) and the escript(s) are referred to via symbolic
links from a bin directory in the path.
EXPORTS
script-name script-arg1 script-arg2...
escript escript-flags script-name script-arg1 script-arg2...
escript runs a script written in Erlang.
Example:
$ chmod u+x factorial
$ cat factorial
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -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
The header of the Erlang script in the example differs from a
normal Erlang module. The first line is intended to be the
interpreter line, which invokes escript.
However, if you invoke the escript as follows, the contents of
the first line do not matter, but it cannot contain Erlang code
as it will be ignored:
$ escript factorial 5
The second line in the example contains an optional directive to
the Emacs editor, which causes it to enter the major mode for
editing Erlang source files. If the directive is present, it
must be located on the second line.
If a comment selecting the encoding exists, it can be located on
the second line.
Note:
The encoding specified by the above mentioned comment applies to
the script itself. The encoding of the I/O-server, however, must
be set explicitly as follows:
io:setopts([{encoding, unicode}])
The default encoding of the I/O-server for standard_io is
latin1, as the script runs in a non-interactive terminal (see
section Summary of Options) in the STDLIB User's Guide.
On the third line (or second line depending on the presence of
the Emacs directive), arguments can be specified to the emula-
tor, for example:
%%! -sname factorial -mnesia debug verbose
Such an argument line must start with %%! and the remaining line
is interpreted as arguments to the emulator.
If you know the location of the escript executable, the first
line can directly give the path to escript, for example:
#!/usr/local/bin/escript
As any other type of scripts, Erlang scripts do not work on Unix
platforms if the execution bit for the script file is not set.
(To turn on the execution bit, use chmod +x script-name.)
The remaining Erlang script file can either contain Erlang
source code, an inlined beam file, or an inlined archive file.
An Erlang script file must always contain the main/1 function.
When the script is run, the main/1 function is called with a
list of strings representing the arguments specified to the
script (not changed or interpreted in any way).
If the main/1 function in the script returns successfully, the
exit status for the script is 0. If an exception is generated
during execution, a short message is printed and the script ter-
minates with exit status 127.
To return your own non-zero exit code, call halt(ExitCode), for
example:
halt(1).
To retrieve the pathname of the script, call
escript:script_name() from your script (the pathname is usually,
but not always, absolute).
If the file contains source code (as in the example above), it
is processed by the epp preprocessor. This means that you, for
example, can use predefined macros (such as ?MODULE) and include
directives like the -include_lib directive. For example, use
-include_lib("kernel/include/file.hrl").
to include the record definitions for the records used by func-
tion file:read_link_info/1. You can also select encoding by
including an encoding comment here, but if a valid encoding com-
ment exists on the second line, it takes precedence.
The script is checked for syntactic and semantic correctness
before it is run. If there are warnings (such as unused vari-
ables), they are printed and the script will still be run. If
there are errors, they are printed and the script will not be
run and its exit status is 127.
Both the module declaration and the export declaration of the
main/1 function are optional.
By default, the script will be interpreted. You can force it to
be compiled by including the following line somewhere in the
script file:
-mode(compile).
Execution of interpreted code is slower than compiled code. If
much of the execution takes place in interpreted code, it can be
worthwhile to compile it, although the compilation itself takes
a little while.
As mentioned earlier, a script can contains precompiled beam
code. In a precompiled script, the interpretation of the script
header is the same as in a script containing source code. This
means that you can make a beam file executable by prepending the
file with the lines starting with #! and %%! mentioned above. In
a precompiled script, the main/1 function must be exported.
Another option is to have an entire Erlang archive in the
script. In an archive script, the interpretation of the script
header is the same as in a script containing source code. This
means that you can make an archive file executable by prepending
the file with the lines starting with #! and %%! mentioned
above. In an archive script, the main/1 function must be
exported. By default the main/1 function in the module with the
same name as the basename of the escript file is invoked. This
behavior can be overridden by setting flag -escript main Module
as one of the emulator flags. Module must be the name of a mod-
ule that has an exported main/1 function. For more information
about archives and code loading, see code(3).
It is often very convenient to have a header in the escript,
especially on Unix platforms. However, the header is optional,
so you directly can "execute" an Erlang module, Beam file, or
archive file without adding any header to them. But then you
have to invoke the script as follows:
$ escript factorial.erl 5
factorial 5 = 120
$ escript factorial.beam 5
factorial 5 = 120
$ escript factorial.zip 5
factorial 5 = 120
escript:create(FileOrBin, Sections) -> ok | {ok, binary()} | {error,
term()}
Types:
FileOrBin = filename() | 'binary'
Sections = [Header] Body | Body
Header = shebang | {shebang, Shebang} | comment | {comment,
Comment} | {emu_args, EmuArgs}
Shebang = string() | 'default' | 'undefined'
Comment = string() | 'default' | 'undefined'
EmuArgs = string() | 'undefined'
Body = {source, SourceCode} | {beam, BeamCode} | {archive,
ZipArchive} | {archive, ZipFiles, ZipOptions}
SourceCode = BeamCode = file:filename() | binary()
ZipArchive = zip:filename() | binary()
ZipFiles = [ZipFile]
ZipFile = file:filename() | {file:filename(), binary()} |
{file:filename(), binary(), file:file_info()}
ZipOptions = [ zip:create_option()]
Creates an escript from a list of sections. The sections can be
specified in any order. An escript begins with an optional
Header followed by a mandatory Body. If the header is present,
it does always begin with a shebang, possibly followed by a com-
ment and emu_args. The shebang defaults to "/usr/bin/env
escript". The comment defaults to "This is an -*- erlang -*-
file". The created escript can either be returned as a binary or
written to file.
As an example of how the function can be used, we create an
interpreted escript that uses emu_args to set some emulator
flag. In this case, it happens to set number of schedulers with
+S3. We also extract the different sections from the newly cre-
ated script:
> 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"...>>}]}
An escript without header can be created as follows:
> 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"
Here we create an archive script containing both Erlang code and
Beam code, then we iterate over all files in the archive and
collect their contents and some information about them:
> {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"...>>}]}
escript:extract(File, Options) -> {ok, Sections} | {error, term()}
Types:
File = filename()
Options = [] | [compile_source]
Sections = Headers Body
Headers = {shebang, Shebang} {comment, Comment} {emu_args,
EmuArgs}
Shebang = string() | 'default' | 'undefined'
Comment = string() | 'default' | 'undefined'
EmuArgs = string() | 'undefined'
Body = {source, SourceCode} | {source, BeamCode} | {beam,
BeamCode} | {archive, ZipArchive}
SourceCode = BeamCode = ZipArchive = binary()
Parses an escript and extracts its sections. This is the reverse
of create/2.
All sections are returned even if they do not exist in the
escript. If a particular section happens to have the same value
as the default value, the extracted value is set to the atom
default. If a section is missing, the extracted value is set to
the atom undefined.
Option compile_source only affects the result if the escript
contains source code. In this case the Erlang code is automati-
cally compiled and {source, BeamCode} is returned instead of
{source, SourceCode}.
Example:
> 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}]}
escript:script_name() -> File
Types:
File = filename()
Returns the name of the escript that is executed. If the func-
tion is invoked outside the context of an escript, the behavior
is undefined.
OPTIONS ACCEPTED BY ESCRIPT
-c:
Compiles the escript regardless of the value of the mode attribute.
-d:
Debugs the escript. Starts the debugger, loads the module contain-
ing the main/1 function into the debugger, sets a breakpoint in
main/1, and invokes main/1. If the module is precompiled, it must
be explicitly compiled with option debug_info.
-i:
Interprets the escript regardless of the value of the mode
attribute.
-s:
Performs a syntactic and semantic check of the script file. Warn-
ings and errors (if any) are written to the standard output, but
the script will not be run. The exit status is 0 if any errors are
found, otherwise 127.
Note:
The configuration of the Erlang emulator invoked by escript can be con-
trolled using the environment variables understood by erl.
Ericsson AB erts 12.2 escript(1)