What 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.
What 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
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.
Install batteries and then depend on it as a library, then:
BatUnix.run_and_read 'cmd'
Its interface is:
val BatUnix.run_and_read string -> BatUnix.process_status * string
© 2022 - 2024 — McMap. All rights reserved.