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

bvpmtnay  于 12个月前  发布在  Erlang
关注(0)|答案(2)|浏览(120)

我正在使用一个端口来运行一个管道,其中包含解压缩和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不会杀死进程,你只是不知道它什么时候完成。是这样吗?

5m1hhzi4

5m1hhzi41#

如果你只需要等待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(也许已经存在一些开源实现?)
  • 使用一些外部脚本和控制协议,例如,可以在实际内容之前传输完整(或块)长度,这样脚本就知道何时关闭连接
uidvcgyl

uidvcgyl2#

可以在这里找到一些相当丑陋的解决方法:limitations of erlang:open_port() and os:cmd()
有些人甚至使用netcat将问题Map到tcp连接。

相关问题