[英]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
正是我想看到的。
編輯:我終於決定將腳本文件(帶有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.