Question

Based on Chapter 12 of the OTP in Action book and Cesarini's book I wrote this Erlang code:

Erlang:

p(Param) ->

    ?DBG("Starting~n", []),

    Cmd = "python test.py",

    Port = open_port({spawn,Cmd}, [stream,{line, 1024},  exit_status]),
    ?DBG("Opened the port: ~w~n", [Port]),

    Payload = term_to_binary(list_to_binary(integer_to_list(Param))),
    erlang:port_command(Port, Payload),

    ?DBG("Sent command to port: ~w~n", [Payload]),
    ?DBG("Ready to receive results for command: ~w~n", [Payload]),

    receive
        {Port, {data, Data}} ->
            ?DBG("Received data: ~w~n", [Data]),
            {result, Text} = binary_to_term(Data),
            Blah = binary_to_list(Text),
            io:format("~p~n", [Blah]);
        Other ->
            io:format("Unexpected data: ~p~n", [Other])

    end.

Python:

import sys
def main():
    while True:
        line = sys.stdin.readline().strip()
        if line == "stop-good":
                return 0
        elif line == "stop-bad":
                return 1
        sys.stdout.write("Python got ")
        sys.stdout.write(line)
        sys.stdout.write("\n")
        sys.stdout.flush()
if __name__ == "__main__":
 sys.exit(main())

The Erlang code suspends at the recieve clause - it never gets any message.

I have also checked Python from a regular Linux shell - it prints out every user input (1 - "Python got 1").

Where is the mistake here? Why doesn't my Erlang code get anything back?

Était-ce utile?

La solution

There are two points:

  • make sure that Python does not buffer your output, try running python -u in open_port
  • using term_to_binary/1 and binary_to_term/1 won't work, since they assume that Python is able to encode/decode Erlang External Term Format, which does not seem to be the case. If you want to go this route, check out ErlPort

Autres conseils

Does your Param contain the command limiter for Python? (in this case I assume newline, "\n"). Also, list_to_binary/1 and then a term_to_binary/1 feels kinda wrong. term_to_binary/1 directly (including the newline) should be sufficient.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top