我有一个外部的exe程序,它从stdin读取数据并产生一个结果。它的工作原理类似于wc
程序,一直读取到EOF(或者说流的结尾)。
- 更新:* 让我再补充一点说明:我基本上是在尝试编写一个Erlang管道。
我可以在批处理文件中调用这个程序,比如echo 339371249625 | LookupProj.exe
,但是我希望能够从Erlang gen_server
向它传递数据。
我看过Erlang Ports,但我很难让他们表现好。以下是我的想法:
test(InputText) ->
P = open_port({spawn, "/ExternEvent/LookupProj.exe"}, [stream, exit_status, use_stdio,
stderr_to_stdout, in, out]),
IBin = list_to_binary(InputText),
%% io:format("~p~n",[I2]),
P ! {self(), {command, <<IBin/binary, <<26>>/binary>>}}, %% ASCII 26 = EOF
P ! {self(), {eof}}, %% ERROR -- how to close stdin of the cat process?
receive B -> io:format("~p",[B]) end.
我试过在open_port
中使用eof
标志,但没有任何帮助。(不确定这是否是正确的标志?)
我哪里做错了?谢谢!
2条答案
按热度按时间hgc7kmma1#
如果我没理解错的话,您正在尝试在多个调用之间重用端口连接,如echo 339371249625|LookupProj.exe,但是关闭stdin的唯一方法实际上是使用port_close/1关闭端口,所以所有这些围绕端口的操作并不比使用os:cmd/1启动命令好。
如果你可以修改LookupProj.exe,你会想考虑一些预定义的字节序列在stdin作为命令的结尾,只是发送它,每次你完成,而不是EOF。
bjp0bcyl2#
根据 [erlang-questions] Issues with stdin on ports,目前无法仅关闭管道的写入端。
有几种变通方法,其中之一是重定向到一个文件,然后读取它。其他人建议使用某种中间人。
我实现了一个**patch to the spawn_driver**,通过
port_control/3
实现了一个操作0x0112c000
,关闭写文件描述符,替换为/dev/null
,用法如下:产量:
请注意,我的修补程序目前仅支持UNIX,并且是实验性的。