从Erlang打开Python端口:没有回复消息

0 投票
2 回答
799 浏览
提问于 2025-04-17 04:15

根据《OTP in Action》这本书的第12章和Cesarini的书,我写了这段Erlang代码:

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())

这段Erlang代码在接收消息的地方停住了——它根本没有收到任何消息。

我还检查了Python代码,在普通的Linux终端下,它会打印出每个用户输入的内容(比如输入1时,它会显示“Python got 1”)。

这里的错误在哪里呢?为什么我的Erlang代码没有收到任何反馈呢?

2 个回答

1

你的参数里有没有包含Python的命令分隔符?(在这种情况下,我假设是换行符“\n”)。另外,先用list_to_binary/1再用term_to_binary/1感觉有点不太对。直接用term_to_binary/1就可以了,包括换行符在内,这样就足够了。

1

这里有两个要点:

  • 确保 Python 不会缓存你的输出,可以尝试在 open_port 中运行 python -u
  • 使用 term_to_binary/1binary_to_term/1 是行不通的,因为它们假设 Python 能够编码和解码 Erlang 外部术语格式,但看起来并不是这样。如果你想走这条路,可以看看 ErlPort

撰写回答