在Erlang中如何从外部程序的stdout读取数据?

m2xkgtsf  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(122)

下面是我编写的代码:

-module(comments).

-record(comment, {user, contents, id, path, sub_comments}).
-export([sort_comments/1]).

comments2csv(Port, []) -> Port ! {self(), close};
comments2csv(Port, [#comment{user=User, contents=Contents, id=ID, path=Path}|Rest]) when is_integer(User) -> 
    Port ! {self(), {command, list_to_binary(Path ++ ":" ++ integer_to_list(User) ++ ":" ++ integer_to_list(ID) ++ ":" ++ Contents ++ "\n")}},
    comments2csv(Port, Rest).

sort_comments(Comments) ->
    Comments2 = [#comment{user=1, contents="hello", id=1, path="/1/", sub_comments=[]}],
    Port = open_port({spawn_executable, "./comsort"}, [binary]),
    comments2csv(Port, Comments2),
    receive
        {Port, {data, Data}} ->
            io:format("~p~n", [Data]);
        {Port, closed} ->
            io:format("closed~n"),
            receive
                X ->
                    io:format("~p~n", [X])
            end
    end.

它调用一个用Haskell编写的外部程序,当我从shell运行它时,它打印"关闭",然后挂起。我一辈子都搞不懂为什么它不从程序的stdout读取输出。Haskell程序被设置为在从stdin接收完CSV数据后将XML数据打印到stdout,然后退出。
我大致上是基于教程here:

yquaqz18

yquaqz181#

好的,我找到了this,它有一些选项,我需要给予open_port一些选项,以便从stdout接收东西。现在它工作了。
编辑:没关系。看来我尝试做的事情是不可能的。Erlang不允许你关闭stdin的文件描述符,这样comsort就不能收集所有的输入,然后在最后发送xml,因为它永远看不到输入的结尾。

相关问题