erlang 爱尔兰港口:与类似“wc”的程序接口?

fwzugrvs  于 2023-02-06  发布在  Erlang
关注(0)|答案(2)|浏览(178)

我有一个外部的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标志,但没有任何帮助。(不确定这是否是正确的标志?)
我哪里做错了?谢谢!

hgc7kmma

hgc7kmma1#

如果我没理解错的话,您正在尝试在多个调用之间重用端口连接,如echo 339371249625|LookupProj.exe,但是关闭stdin的唯一方法实际上是使用port_close/1关闭端口,所以所有这些围绕端口的操作并不比使用os:cmd/1启动命令好。
如果你可以修改LookupProj.exe,你会想考虑一些预定义的字节序列在stdin作为命令的结尾,只是发送它,每次你完成,而不是EOF。

bjp0bcyl

bjp0bcyl2#

根据 [erlang-questions] Issues with stdin on ports,目前无法仅关闭管道的写入端。
有几种变通方法,其中之一是重定向到一个文件,然后读取它。其他人建议使用某种中间人。
我实现了一个**patch to the spawn_driver**,通过port_control/3实现了一个操作0x0112c000,关闭写文件描述符,替换为/dev/null,用法如下:

-module(test).
-export([wc/1]).

wc(InputText) ->
    P = open_port({spawn, "wc"}, [stream, use_stdio]),
    P ! {self(), {command, InputText}},
    erlang:port_control(P, 16#0112c000, []),
    receive {P, X} -> X end.

产量:

1> test:wc("Hello\nWorld!\n").
{data,"      2       2      13\n"}
2>

请注意,我的修补程序目前仅支持UNIX,并且是实验性的。

相关问题