Go to main content

man pages section 1: User Commands

Exit Print View

Updated: Wednesday, February 10, 2021
 
 

escript (1)

Name

escript - Erlang scripting support

Synopsis

Please see following description for synopsis

Description

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.

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 -*-
              %%! -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

              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 does 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:

              %%! -smp enable -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. Also, native can be supplied instead of compile.
              This compiles the script using the native flag and  may  or  may
              not be worthwhile depending on the escript characteristics.

              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 disable  the  smp_support.  We
              also  extract  the  different  sections  from  the newly created
              script:

              > Source = "%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(smp_support)).\n".
              "%% Demo\nmain(_Args) ->\n    io:format(erlang:system_info(smp_support)).\n"
              > io:format("~s\n", [Source]).
              %% Demo
              main(_Args) ->
                  io:format(erlang:system_info(smp_support)).

              ok
              > {ok, Bin} = escript:create(binary, [shebang, comment, {emu_args, "-smp disable"}, {source, list_to_binary(Source)}]).
              {ok,<<"#!/usr/bin/env escript\n%% This is an -*- erlang -*- file\n%%!-smp disabl"...>>}
              > file:write_file("demo.escript", Bin).
              ok
              > os:cmd("escript demo.escript").
              "false"
              > escript:extract("demo.escript", []).
              {ok,[{shebang,default}, {comment,default}, {emu_args,"-smp disable"},
                   {source,<<"%% Demo\nmain(_Args) ->\n    io:format(erlang:system_info(smp_su"...>>}]}

              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.

         -n:
           Compiles the escript using flag +native.



Ericsson AB                        erts 8.3                         escript(1)