Ocaml lwt从其他进程读取标准输出

Ocaml lwt从其他进程读取标准输出,ocaml,ocaml-lwt,Ocaml,Ocaml Lwt,我正在尝试用Ocaml为基于终端的应用程序构建一个新的前端。主要思想是使用Lwt生成新流程: let cmd = shell "./otherterminalapp" in let p = open_process_full cmd; 然后再将内容写入进程的stdin,以在外部应用程序中执行命令 Lwt_io.write_line p#stdin "some command" >>= (fun _ -> Lwt_io.flush p#stdin) 当我用Lwt\u io.

我正在尝试用Ocaml为基于终端的应用程序构建一个新的前端。主要思想是使用Lwt生成新流程:

let cmd = shell "./otherterminalapp" in
let p = open_process_full cmd;
然后再将内容写入进程的stdin,以在外部应用程序中执行命令

 Lwt_io.write_line p#stdin "some command" >>= (fun _ -> Lwt_io.flush p#stdin)
当我用
Lwt\u io.read\u line\u opt
从命令中读取结果时。我怎么读到一行字都没有了? 我遇到的问题是,我的程序在某个点挂起。当我用
read\u line\u opt
阅读时,当我读到结尾时,它似乎只是在等待进程重定向新的输出

我怎样才能做到这一点

我正在尝试做的一个具体例子: (基于终端的应用程序是ocamldebug)

程序源代码:

open Lwt
open Lwt_unix
open Lwt_process
let () =
  let run () =
    let cmd = shell "ocamldebug test.d.byte" in
    let dbgr = open_process_full cmd in
    (((((((Lwt_io.write_line dbgr#stdin "info modules") >>=
            (fun _  -> Lwt_io.flush dbgr#stdin))
           >>= (fun _  -> Lwt_io.read_line_opt dbgr#stdout))
          >>=
          (fun s  ->
             (match s with
              | Some l -> print_endline l
              | None  -> print_endline "nothing here! ");
             Lwt_io.read_line_opt dbgr#stdout))
         >>=
         (fun s  ->
            (match s with
             | Some l -> print_endline l
             | None  -> print_endline "nothing here! ");
            Lwt_io.read_line_opt dbgr#stdout))
        >>=
        (fun s  ->
           (match s with
            | Some l -> print_endline l
            | None  -> print_endline "nothing here! ");
           Lwt_io.read_line_opt dbgr#stdout))
       >>=
       (fun s  ->
          (match s with
           | Some l -> print_endline l
           | None  -> print_endline "nothing here! ");
          Lwt_io.read_line_opt dbgr#stdout))
      >>=
      (fun s  ->
         (match s with
          | Some l -> print_endline l
          | None  -> print_endline "nothing here! ");
         Lwt.return ()) in
  Lwt_main.run (run ())
如果您通常使用
test.d.byte
运行
ocamldebug
,则会得到 在终端中执行以下操作:

    OCaml Debugger version 4.03.0

(ocd) info modules
Loading program... done.
Used modules: 
Std_exit Test Pervasives CamlinternalFormatBasics
(ocd) 
当我执行上述程序时,我会打印以下内容:

    OCaml Debugger version 4.03.0

(ocd) Loading program... Used modules: 
Std_exit Test Pervasives CamlinternalFormatBasics
在这里它只是挂起…,我的程序没有退出。即使我这样做了 Ctrl-c/Ctrl-c在我的终端中,有一个活动的ocamlrun进程。然而,终端会变得响应迅速


我在这里遗漏了一些明显的东西?

调用
Lwt.read\u line\u opt
返回一个延迟值,该值将在将来通道读取以换行符结尾的字符串时确定为
某些数据,或者在通道关闭时使用
None
。如果存在文件结束条件,则通道将关闭。对于常规文件,当文件指针到达文件末尾时,会出现文件结束条件。对于用于与子流程通信的管道,当对方关闭与管道关联的文件描述符时,会出现文件结束情况

ocamldebug
程序不会关闭其输入或输出。它是一个交互式程序,可以通过点击
Ctrl-D
或使用
quit
命令与用户进行无限时间的交互,或直到用户关闭程序

在您的场景中,您将
info modules
命令写入通道的输入。流程用三行(其中每行都是以换行符结尾的一段数据)进行响应。然后子流程开始等待下一个输入。您没有看到
(ocd)
提示,因为它不是以换行符结尾的。节目没有挂断。它仍在等待子流程的输出,而子流程正在等待您的输入(死锁)

如果确实需要区分不同命令的输出,则需要跟踪子流程输出中的提示。由于提示不是由换行符终止的,因此不能依赖于
read\u line*
函数系列,因为它们是行缓冲的。您需要读取所有可用字符并手动在其中查找提示


另一方面,如果您真的不需要区分不同命令的输出,那么您可以忽略提示(实际上,您甚至可以将其过滤掉,以获得更好的输出)。在这种情况下,您将有两个并发子例程-一个负责输入,另一个将读取所有输出并转储,而不实际携带数据内容

您是否可以展示一个更完整的示例,包括您的阅读方式,以及对另一个进程实际执行的操作的更好描述,或者更好的是,为另一个进程提供一个最少的源代码?什么是“特定点?”你能用
read\u line\u opt
阅读一段时间,然后它就不再“工作”了吗?在什么意义上?当你说“结束”时,你是指一行的结束,另一个进程输出的结束,还是其他什么?另一个进程是否确实退出或关闭了其输出流?我用一个完整的示例更新了问题,说明了我正在尝试完成的任务。您发布的代码在语法上不正确。很抱歉给您带来不便,我修复了语法错误。感谢您的详细回答!