【问题标题】:Erlang: port to Python instance not respondingErlang:端口到 Python 实例没有响应
【发布时间】:2021-06-16 19:38:21
【问题描述】:

我正在尝试通过 Erlang 端口与外部 python 进程通信。首先打开一个端口,然后通过标准输入向外部进程发送一条消息。我期待在进程的标准输出上得到相应的回复。

我的尝试如下所示:

% open a port
Port = open_port( {spawn, "python -u -"},
                  [exit_status, stderr_to_stdout, {line, 1000000}] ).

% send a command to the port
true = port_command( Port, "print( \"Hello world.\" )\n" ).

% gather response
% PROBLEM: no matter how long I wait flushing will return nothing
flush().

% close port
true = port_close( Port ).

% still nothing
flush().

我意识到 someone else on Stackoverflow 试图做类似的事情,但提议的解决方案显然对我不起作用。

另外,我看到a related post on Erlang Central 正在通过 Erlang 端口启动 Python 脚本,但调用的不是 Python shell 本身。

我已经注意到ErlPort,但我有一个完整的脚本要在 Python 中执行。如果可能,我不想将脚本分解为单个 Python 调用。

够有趣的,用 bash 来做是没问题的:

Port = open_port( {spawn, "bash"},
                  [exit_status, stderr_to_stdout, {line, 1000000}] ).

true = port_command( Port, "echo \"Hello world.\"\n" ).

所以上面的例子给了我一个“Hello world”。冲洗时:

3> flush().
Shell got {#Port<0.544>,{data,{eol,"Hello world."}}}
ok

正是我想看到的。

  • Ubuntu 15.04 64 位
  • 二郎18.1
  • Python 2.7.9

编辑: 我最终决定将脚本文件(带有 shebang)写入磁盘并执行脚本文件,而不是将脚本传送到某些语言(如 Python)的语言解释器。

我怀疑,问题与某些解释器缓冲 IO 的方式有关,我无法解决这个问题,因此有必要对磁盘进行额外的一轮。

【问题讨论】:

    标签: python erlang port


    【解决方案1】:

    正如您所发现的,对于这个问题,端口并不能满足您的需求,这就是为什么存在像 ErlPort 这样的替代方案的原因。此问题的旧解决方法是使用netcat 将命令通过管道传输到 python 中,以便发生正确的 EOF。这是一个示例会话:

    1> PortOpts = [exit_status, stderr_to_stdout, {line,1000000}].
    [exit_status,stderr_to_stdout,{line,1000000},use_stdio]
    2> Port = open_port({spawn, "nc -l 51234 | python"}, PortOpts).
    #Port<0.564>
    3> {ok, S} = gen_tcp:connect("localhost", 51234, []).
    {ok,#Port<0.565>}
    4> gen_tcp:send(S, "print 'hello'\nprint 'hello again'\n").
    ok
    5> gen_tcp:send(S, "print 'hello, one more time'\n").
    ok
    6> gen_tcp:close(S).
    ok
    7> flush().
    Shell got {#Port<0.564>,{data,{eol,"hello"}}}
    Shell got {#Port<0.564>,{data,{eol,"hello again"}}}
    Shell got {#Port<0.564>,{data,{eol,"hello, one more time"}}}
    Shell got {#Port<0.564>,{exit_status,0}}
    ok
    

    这种方法在端口 51234 上打开一个运行 netcat 的端口作为侦听器 - 当然,您可以选择任何您希望使用的端口,只要它尚未使用 - 其输出通过管道传输到 python。然后,我们通过本地 TCP 环回连接到netcat,并将 python 命令字符串发送到其中,然后通过管道将其转发到 python。关闭套接字会导致netcat 退出,这会导致 python 的标准输入出现 EOF,进而导致它执行我们发送给它的命令。刷新 Erlang shell 消息队列表明我们通过 Erlang 端口从 python 获得了预期的结果。

    【讨论】:

      猜你喜欢
      • 2015-07-16
      • 1970-01-01
      • 2011-06-02
      • 2018-04-16
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 2011-06-24
      相关资源
      最近更新 更多