开发者

Collecting the output of an external command using OCaml

开发者 https://www.devze.com 2022-12-19 22:13 出处:网络
What开发者_Python百科 is the right way to call an external command and collect its output in OCaml?

What开发者_Python百科 is the right way to call an external command and collect its output in OCaml?

In Python, I can do something like this:

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

How I can get all of an external program's output in OCaml? Or, better, OCaml with Lwt?

Thanks.


You want Unix.open_process_in, which is described on page 388 of the OCaml system manual, version 3.10.


For Lwt,

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

seems to be a good contender. Documentation here: 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


There are lots of examples on PLEAC.


You can use the third party library Rashell which uses Lwt to define some high-level primitives to read output from processes. These primitives, defined in the module Rashell_Command, are:

  • exec_utility to read the output of a process as a string;
  • exec_test to only read the exit status of a process;
  • exec_query to read the output of a process line by line as a string Lwt_stream.t
  • exec_filter to use an external program as a string Lwt_stream.t -> string Lwt_stream.t transformation.

The command function is used to create command contexts on which the previous primitives can be applied, it has the signature:

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]. *)

So for instance

Rashell_Command.(exec_utility ~chomp:true (command("", [| "uname" |])))

is a string Lwt.t which returns the “chomped” string (new line removed) of the “uname” command. As a second example

Rashell_Command.(exec_query (command("", [| "find"; "/home/user"; "-type"; "f"; "-name"; "*.orig" |])))

is a string Lwt_stream.t whose elements are the paths of the file found by the command

find /home/user -type f -name '*.orig'

The Rashell library defines also interfaces to some commonly used commands, and a nice interface to the find command is defined in Rashell_Posix – which by the way guarantees POSIX portability.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号