[erlang-questions] ErlExec stdin and other questions

Serge Aleynikov <>
Sun Aug 11 07:21:46 CEST 2013


I fixed the STDOUT buffering issue with erlexec.  Now all STDOUT and
STDERR output should arrive as soon as the child OS process generates it:

1> exec:start([]).
{ok, <0.35.0>}
2> exec:run("for i in 1 2 3; do sleep 1; echo \"Iter$i\"; done",
[{stdout, fun(S,OsPid,D) -> io:format("Got ~w from ~w: ~p\n",
[S,OsPid,D]) end}]).
{ok,<0.37.0>,2452}
Got stdout from 2452: <<"Iter1\n">>
Got stdout from 2452: <<"Iter2\n">>
Got stdout from 2452: <<"Iter3\n">>

See https://github.com/saleyn/erlexec.

On Wed, Aug 7, 2013 at 3:36 AM, OvermindDL1 <
<mailto:>> wrote:

    Created a complete test-case example of my issue with erlexec, and I
    ran this same script on 3 different computers running variations of
    debian versions.  Feel free to toss in application:start(sasl), at
    the top of the erlang script area if you wish, and yes the
    (minecraft) server software uses stderr instead of stdout, no I do
    not know why, and yes as you can see it does not return anything to
    the erlang system until it is killed on all the systems I tested.
     Using Erlang's ports you get each line as a message as that is how
    the server flushes it and it is instant.


    Yes it is ugly, but it is pared down from what it grew from and no
    need to re-do the receive's better in such a test.
    test_exec_mc.sh
    """
    #!/bin/sh

    [ -d erlexec ] || git clone https://github.com/saleyn/erlexec.git

    cd erlexec

    rebar compile

    [ -f 'minecraft_server.1.6.2.jar' ] || wget
    'https://s3.amazonaws.com/Minecraft.Download/versions/1.6.2/minecraft_server.1.6.2.jar'

    erl -pa $PWD/ebin -eval '
    application:start(exec),
    {_, P, _} = exec:run_link("java -Xms1G -Xmx1G -jar
    minecraft_server.1.6.2.jar nogui", [{stdout, self()}, {stderr,
    self()}]),
    timer:sleep(1000),
    receive A0 -> io:format("Message ~p: ~p~n", [now(), A0]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    receive A1 -> io:format("Message ~p: ~p~n", [now(), A1]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    receive A2 -> io:format("Message ~p: ~p~n", [now(), A2]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    receive A3 -> io:format("Message ~p: ~p~n", [now(), A3]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    receive A4 -> io:format("Message ~p: ~p~n", [now(), A4]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    timer:sleep(1000),
    receive A5 -> io:format("Message ~p: ~p~n", [now(), A5]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    receive A6 -> io:format("Message ~p: ~p~n", [now(), A6]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    receive A7 -> io:format("Message ~p: ~p~n", [now(), A7]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    receive A8 -> io:format("Message ~p: ~p~n", [now(), A8]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    receive A9 -> io:format("Message ~p: ~p~n", [now(), A9]) after 1000
    -> io:format("timeout ~p~n", [now()]) end,
    timer:sleep(10000),
    receive A10 -> io:format("Message ~p: ~p~n", [now(), A10]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A11 -> io:format("Message ~p: ~p~n", [now(), A11]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A12 -> io:format("Message ~p: ~p~n", [now(), A12]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A13 -> io:format("Message ~p: ~p~n", [now(), A13]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A14 -> io:format("Message ~p: ~p~n", [now(), A14]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    exec:kill(P, 9),
    receive A15 -> io:format("Message ~p: ~p~n", [now(), A15]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A16 -> io:format("Message ~p: ~p~n", [now(), A16]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A17 -> io:format("Message ~p: ~p~n", [now(), A17]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A18 -> io:format("Message ~p: ~p~n", [now(), A18]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A19 -> io:format("Message ~p: ~p~n", [now(), A19]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    timer:sleep(1000),
    receive A20 -> io:format("Message ~p: ~p~n", [now(), A20]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A21 -> io:format("Message ~p: ~p~n", [now(), A21]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A22 -> io:format("Message ~p: ~p~n", [now(), A22]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A23 -> io:format("Message ~p: ~p~n", [now(), A23]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    receive A24 -> io:format("Message ~p: ~p~n", [now(), A24]) after
    1000 -> io:format("timeout ~p~n", [now()]) end,
    q().'
    """





    On Tue, Aug 6, 2013 at 10:49 PM, OvermindDL1 <
    <mailto:>> wrote:

        Excepting this, is there any other better way to launch a
        program as another user?  I might just use ssh certs and ssh to
        localhost if not unless any other ideas?


        On Tue, Aug 6, 2013 at 4:22 AM, OvermindDL1
        < <mailto:>> wrote:

            I have been attempting to use ErlExec as I noticed that it
            had a few new features added six days ago to forward the
            stdout/stderr to an Erlang PID, however I am having some
            issue.  The process that erlexec runs occasionally does not
            die when the Erlang VM dies, thus keeping it and its
            children running.

            Also I need a way to send commands back to the children, but
            I am either not seeing a command for that or have not
            figured out the format to send a message, which is difficult
            because of the main issue I have, when I have it launch a
            fairly large server software (that is not a daemon for
            whatever reason, hence why I am wrapping it), the Erlang
            shell seems to lose a great deal of input that I type in,
            only catching from every 1 in 4 I type to 1 in 400
            characters I type, and it does not seem to matter based on
            the speed I hit keys or holding a key or anything of the
            sort, just purely on keypress down, and it remains like that
            until I kill the child process that I started through erlexec.

            Using the normal Erlang Ports works fine and has no such
            issues (other than the child not coming down with the VM
            either and no direct kill command when the child hangs,
            which it occasionally does, but os:cmd("kill ...") works
            around that well enough.

            Is ErlExec stable enough for high use?  Or am I doing
            something wrong?




    _______________________________________________
    erlang-questions mailing list
     <mailto:>
    http://erlang.org/mailman/listinfo/erlang-questions


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130811/f535e6dd/attachment.html>


More information about the erlang-questions mailing list