Erlang:端口到Python实例没有响应 [英] Erlang: port to Python instance not responding

查看:69
本文介绍了Erlang:端口到Python实例没有响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过Erlang端口与外部python进程进行通信.首先,打开端口,然后通过stdin将消息发送到外部进程.我希望对流程的标准输出有相应的答复.

I am trying to communicate to an external python process through an Erlang port. First, a port is opened, then a message is sent to the external process via stdin. I am expecting a corresponding reply on the process's stdout.

我的尝试如下:

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

我意识到 Stackoverflow上的其他人试图做类似的事情,但建议的解决方案显然对我不起作用.

I realize that someone else on Stackoverflow tried to do something similar but the proposed solution apparently doesn't work for me.

此外,我看到有关Erlang Central的相关帖子正在启动Python通过Erlang端口编写脚本,但是调用的不是Python shell本身.

Also, I see that a related post on Erlang Central is starting a Python script through an Erlang port but it is not the Python shell itself that is invoked.

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

I have taken notice of ErlPort but I have a whole script to be executed in Python. If possible, I wouldn't want to break up the script into single Python calls.

很有趣,用bash进行操作没问题:

Funny enough, doing it with bash is no problem:

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

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

因此,上面的示例为我提供了一个"Hello world".冲洗时:

So the above example gives me a "Hello world." on flushing:

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)的语言解释器.

I have finally decided to write a script file (with a shebang) to disk and execute the script file instead of piping the script to the language interpreter for some languages (like Python).

我怀疑,问题与某些解释器缓冲IO的方式有关,而我只是无法解决此问题,因此有必要对此磁盘进行额外的回合.

I suspect, the problem has to do with the way some interpreters buffer IO, which I just can't work around, making necessary this extra round to disk.

推荐答案

正如您所发现的那样,端口无法满足您对这个问题的要求,这就是为什么

As you've discovered, ports don't do what you'd like for this problem, which is why alternatives like ErlPort exist. An old workaround for this problem is to use netcat to pipe commands into python so that a proper EOF occurs. Here's an example session:

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

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

This approach opens a port running netcat as a listener on port 51234 — you can choose whatever port you wish to, of course, as long as its not already in use — with its output piped into python. We then connect to netcat over the local TCP loopback and send python command strings into it, which it then forwards through its pipe to python. Closing the socket causes netcat to exit, which results in an EOF on python's stdin, which in turn causes it to execute the commands we sent it. Flushing the Erlang shell message queue shows we got the results we expected from python via the Erlang port.

这篇关于Erlang:端口到Python实例没有响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆