[erlang-questions] escript question

Tim Watson watson.timothy@REDACTED
Mon Sep 19 11:17:11 CEST 2011


On 18 September 2011 22:15, Chris Hicks <silent_vendetta@REDACTED> wrote:

>  I was thinking about this some more, and doing some more reading, and if I
> have a process which uses os:cmd on a unix box to run the escript and if
> doing so starts up a full Erlang node, is there any reason that the Pid of
> the calling process couldn't be passed as one of the arguments? Couldn't the
> script simply send a message to that Pid and once the script exits and
> returns a value to the process that called os:cmd, that process would then
> do a receive to retrieve the message?
>

As I said previously, I'm not 100% sure about escripts being part of a
distributed system, but check it out and see if it works.

In terms of passing on the pid, as Jon mentioned you should probably pass on
a globally registered name, which you can handle with either the global
module or https://github.com/esl/gproc (I favour the latter personally).

I'd also suggest rather than using os:cmd, that you consider
erlang:open_port so that you can check the return code to see whether the
script executed successfully or not. I'll post an example at the bottom of
this main.


>
> On a related note, can an escript be run as a text string instead of a file
> residing on the system? Basically, I'm trying to figure out if I can just
> hold all my scripts in a DB, pull them out as needed and execute them rather
> than actually creating a file that is run.
>

Yes sort of. The escript module has functions to handle this kind of thing,
for example from http://www.erlang.org/doc/man/escript.html:

{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).

You can also zip together a bunch of module beam files to form into an
escript, which allows you to guarantee modules will be loaded by the code
server when the script is executed. Rebar provides support for doing this as
part of a build process: take a look at
https://github.com/basho/rebar/blob/master/src/rebar_escripter.erl to see
how it works. Using a mechanism like this, you could store a blob containing
the code and pull this out at runtime, optionally modify it and then write
it to a temporary file location prior to executing the script(s).

To get feedback from the executable, you can do something like this quick,
not production worthy, hack:

exec(Command) ->
    exec(Command, []).

exec(Command, Env) ->
    PortSettings = [exit_status, {line, 16384}, stderr_to_stdout, hide],
    sh_loop(open_port({spawn, Command}, PortSettings ++ Env), []).

sh_loop(Port, Acc) ->
    receive
        {Port, {data, {eol, Line}}} ->
            sh_loop(Port, [Line ++ "\n" | Acc]);
        {Port, {data, {noeol, Line}}} ->
            sh_loop(Port, [Line | Acc]);
        {Port, {exit_status, 0}} ->
            {ok, lists:flatten(lists:reverse(Acc))};
        {Port, {exit_status, Rc}} ->
            {error, {Rc, lists:flatten(lists:reverse(Acc))}}
    end.


Cheers,

Tim

------------------------------
> From: silent_vendetta@REDACTED
> To: watson.timothy@REDACTED
> Date: Sun, 18 Sep 2011 10:57:24 -0700
>
> CC: erlang-questions@REDACTED
> Subject: Re: [erlang-questions] escript question
>
>  Thanks for the response, Tim. The first two were along the lines of what I
> was thinking I'd need to do, though I didn't know about file:consult/1 which
> could come in very handy for a couple other things I'm working on. I'm
> leaning a bit more towards #1 though simply because in the system I'm
> building there could be anywhere from dozens to hundreds of these scripts
> being fired off each second and, without having spent much time thinking
> about it, I imagine trying to filter the appropriate structure back to the
> appropriate process which fired off the escript via method #2 would just add
> some unnecessary complexity.
>
> ------------------------------
> Date: Sun, 18 Sep 2011 18:44:24 +0100
> Subject: Re: [erlang-questions] escript question
> From: watson.timothy@REDACTED
> To: silent_vendetta@REDACTED
> CC: erlang-questions@REDACTED
>
> 1. write it to a file and use file:consult/1 to grab the result.
> 2. write it back to stdout and use erl_parse/erl_eval
> 3. use emu_args to get the escript hooked into the distribution protocol
> and use rcp:call to send the result back
>
> Not actually sure about (3) as I've never done that, but the other two work
> fine and are simple to implement.
>
> Cheers,
>
> Tim
>
> On 18 September 2011 17:49, Chris Hicks <silent_vendetta@REDACTED>wrote:
>
>  Quick question, what would be considered the easiest way to "return" data
> to a running Erlang application from an escript? For example I might want to
> run an escript with a data structure I want it to modify and, once it is all
> done, get the modified structure back.
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
>
> _______________________________________________ erlang-questions mailing
> list erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110919/e6ff579c/attachment.htm>


More information about the erlang-questions mailing list