端末ベースのアプリケーション用に Ocaml で新しいフロントエンドを構築しようとしています。主なアイデアは、Lwt を使用して新しいプロセスを生成することです。
let cmd = shell "./otherterminalapp" in
let p = open_process_full cmd;
その後、プロセスの標準入力に何かを書き込んで、外部アプリでコマンドを実行します。
Lwt_io.write_line p#stdin "some command" >>= (fun _ -> Lwt_io.flush p#stdin)
コマンドからの結果を読み取ると、Lwt_io.read_line_opt
. 行がなくなるまで読むにはどうすればよいですか?私が直面している問題は、プログラムが特定の時点でハングすることです。で読むとread_line_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 ())
通常は で実行するocamldebug
とtest.d.byte
、端末に次のように表示されます。
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 プロセスがあります。ただし、端末は応答します。
ここで明らかな何かが欠けていますか?