[erlang-questions] struggling with port_command()

Hynek Vychodil <>
Fri Oct 22 16:26:20 CEST 2010


On Thu, Oct 21, 2010 at 10:39 PM, Gregory Haskins
<> wrote:
> Hi All,
>
> I've been struggling all afternoon with what is perhaps a completely trivial problem, but I can't seem to get past it.
>
> Ultimately, I want to be able to have a simple external port program transform a string (XML, in fact, but that shouldn't matter).  So I want to have my erlang program pump a string in on stdin, and then get a string back out on stdout.  Simple stuff, but it just will not work for me.
>
> I scoured the net for examples and/or threads on problems in doing this, but was unable to figure out what I am doing wrong.  Here is an escript which exemplifies the issue:
>
> #!/usr/bin/env escript
>
> pipe_stdin(Port) ->
>    case io:get_line("") of
>        eof ->
>            %port_close(Port),
>            ok;
>        Data ->
>            true = port_command(Port, Data),
>            pipe_stdin(Port)
>    end.
>
> main([Cmd]) ->
>    io:format("Executing ~s~n", [Cmd]),
>    Port = erlang:open_port({spawn, Cmd}, [stream, use_stdio, exit_status]),
>
>    ok = pipe_stdin(Port),
>    {ok, _Status, Output} = cmd_receive(Port, ""),
>
>    io:format("-----~s~n", [Output]),
>
>    ok.
>
> cmd_receive(Port, Acc) ->
>    receive
>        {Port, {data, Data}} ->
>            cmd_receive(Port, string:concat(Acc, Data));
>        {Port, {exit_status, Status}} ->
>            {ok, Status, Acc};
>        Else ->
>            throw({unexpected_msg, Else})
>    end.
>
> The problem I am seeing is that the data never seems to reach the port program (with or without the port_close()).  I pump the data in with port_command() and it returns "true" but nothing seems to come out the other side.  Any help would be greatly appreciated.
>
> -Greg
>
> PS: As a secondary question, is the right way to signal EOF on the stdin to the port to use port_close()?

1> Port = open_port({spawn, "cat"}, [stream]).
#Port<0.522>
2> port_command(Port, "Hello World\n").
true
3> flush().
Shell got {#Port<0.522>,{data,{eol,"Hello World\n"}}}
ok
4> port_close(Port).
true

Are you sure that data doesn't arrive to your port program? It seems
that your port program is unable detect end of input data because
there is not possible send eof (or I don't know how). When you use
stream option it is up to you implement correct wire protocol. May be
you have to make some wrapper around your port program.

-- 
--Hynek (Pichi) Vychodil

Analyze your data in minutes. Share your insights instantly. Thrill
your boss.  Be a data hero!
Try GoodData now for free: www.gooddata.com


More information about the erlang-questions mailing list