我正在尝试通过Erlang端口与外部python进程进行通信。首先,打开端口,然后通过stdin将消息发送到外部进程。我期望对流程的标准输出有相应的答复。
我的尝试如下所示:
% 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位
Erlang 18.1
Python 2.7.9
编辑:
我最终决定将一个脚本文件(带有shebang)写入磁盘并执行该脚本文件,而不是将脚本通过管道传递给某些语言(例如Python)的语言解释器。
我怀疑,问题与某些解释器缓冲IO的方式有关,而我只是无法解决此问题,因此有必要对磁盘进行额外的处理。
最佳答案
正如您所发现的那样,端口无法解决该问题,这就是为什么存在诸如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的stdin上导致EOF,进而使它执行我们发送给它的命令。刷新Erlang Shell消息队列显示,我们通过Erlang端口从python获得了预期的结果。关于python - Erlang:端口到Python实例没有响应,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33278401/