在外部端口上如何只关闭输出并等待exit_status

时间:2011-07-04 11:20:14

标签: erlang

我使用端口来运行具有解压缩的管道和dd的一些数据:

Port = open_port({spawn, "bzcat | sudo dd of=/dev/foo}, 
                 [stream, use_stdio, exit_status]),

我想要做的是在输出上产生一个文件结束情况,导致管道完成并最终退出。

我想等待此次完成并抓取exit_status

当我打电话给port_close时,它看起来好像管道刚刚终止而且没有等待完成。我也没有得到exit_status ....

如何在下一步(要求dd完成)之前完成等待退出。

做了一些实验,看起来至少port_close并没有杀死这个过程,你只是不知道它什么时候完成。这是对的吗?

2 个答案:

答案 0 :(得分:3)

如果您只需要等待open_port命令生成完成,则需要等待exit_status消息:

1> Port = open_port({spawn, "sleep 7"}, [exit_status]).                   
#Port<0.497>
2> receive {Port, {exit_status, Code}} -> Code after 10000 -> timeout end.
0

更新(即将关闭输出管道的端口):我认为您不能只使用默认的spawn驱动程序关闭输出管道。默认驱动程序没有任何控制命令和port_close,尽管不会杀死生成的命令但会完全擦除所有端口的状态。

可能的解决方案:

  • 首先将输入流写入文件,然后在该文件上运行bzip/dd序列;
  • 编写自己的驱动程序或NIF(可能已经存在一些开源实现?)
  • 使用一些外部脚本和控制协议,例如可以在实际内容之前传输完整(或块)长度,以便脚本知道何时关闭连接

答案 1 :(得分:0)

这里可以找到几个相当丑陋的解决方法:limitations of erlang:open_port() and os:cmd()

有些人甚至使用netcat将问题映射到tcp连接。