【发布时间】:2010-02-06 22:20:23
【问题描述】:
调用外部命令并在 OCaml 中收集其输出的正确方法是什么?
在 Python 中,我可以这样做:
os.popen('cmd').read()
如何在 OCaml 中获取所有外部程序的输出?或者,更好的是带有 Lwt 的 OCaml?
谢谢。
【问题讨论】:
调用外部命令并在 OCaml 中收集其输出的正确方法是什么?
在 Python 中,我可以这样做:
os.popen('cmd').read()
如何在 OCaml 中获取所有外部程序的输出?或者,更好的是带有 Lwt 的 OCaml?
谢谢。
【问题讨论】:
您想要Unix.open_process_in,这在 OCaml 系统手册 3.10 版的第 388 页中有描述。
【讨论】:
对于 Lwt,
val pread : ?env:string array -> command -> string Lwt.t
似乎是一个很好的竞争者。此处的文档:http://ocsigen.org/docu/1.3.0/Lwt_process.html
【讨论】:
let process_output_to_list2 = fun command ->
let chan = Unix.open_process_in command in
let res = ref ([] : string list) in
let rec process_otl_aux () =
let e = input_line chan in
res := e::!res;
process_otl_aux() in
try process_otl_aux ()
with End_of_file ->
let stat = Unix.close_process_in chan in (List.rev !res,stat)
let cmd_to_list command =
let (l,_) = process_output_to_list2 command in l
【讨论】:
PLEAC上有很多例子。
【讨论】:
您可以使用第三方库Rashell,它使用 Lwt 定义一些高级原语来读取进程的输出。这些在模块Rashell_Command 中定义的原语是:
exec_utility 将进程的输出读取为字符串;exec_test 只读取进程的退出状态;exec_query 将进程的输出逐行读取为string Lwt_stream.t
exec_filter 使用外部程序作为string Lwt_stream.t -> string Lwt_stream.t 转换。command 函数用于创建可以应用先前原语的命令上下文,它具有签名:
val command : ?workdir:string -> ?env:string array -> string * (string array) -> t
(** [command (program, argv)] prepare a command description with the
given [program] and argument vector [argv]. *)
例如
Rashell_Command.(exec_utility ~chomp:true (command("", [| "uname" |])))
是一个string Lwt.t,它返回“uname”命令的“chomped”字符串(删除了新行)。作为第二个例子
Rashell_Command.(exec_query (command("", [| "find"; "/home/user"; "-type"; "f"; "-name"; "*.orig" |])))
是一个string Lwt_stream.t,其元素是命令找到的文件的路径
find /home/user -type f -name '*.orig'
Rashell 库还定义了一些常用命令的接口,Rashell_Posix 中定义了一个很好的find 命令接口——顺便保证了 POSIX 的可移植性。
【讨论】: