使用OCaml收集外部命令的输出

时间:2010-02-06 22:20:23

标签: unix ocaml

在OCaml中调用外部命令并收集其输出的正确方法是什么?

在Python中,我可以这样做:

os.popen('cmd').read()

如何在OCaml中获取所有外部程序的输出?或者,更好的是,OCaml与Lwt?

感谢。

5 个答案:

答案 0 :(得分:14)

您需要Unix.open_process_in,这在OCaml系统手册3.10版的第388页中有所描述。

答案 1 :(得分:7)

对于Lwt,

  

val pread:?env:string array - >命令 - > string Lwt.t

似乎是一个很好的竞争者。这里的文档:http://ocsigen.org/docu/1.3.0/Lwt_process.html

答案 2 :(得分:4)

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

答案 3 :(得分:2)

PLEAC上有很多例子。

答案 4 :(得分:2)

您可以使用第三方库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库还定义了一些常用命令的接口,find命令的一个很好的接口在Rashell_Posix中定义 - 这样可以保证POSIX的可移植性。