簡體   English   中英

Erlang:Python 實例的端口沒有響應

[英]Erlang: port to Python instance not responding

我正在嘗試通過 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().

我意識到Stackoverflow上的其他人試圖做類似的事情,但提出的解決方案顯然對我不起作用。

另外,我看到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
  • 蟒蛇 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 獲得了預期的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM