Сбор вывода внешней команды с помощью OCaml

Каков правильный способ вызова внешней команды и сбора ее вывода в OCaml?

В Python я могу сделать что-то вроде этого:

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

Как я могу получить весь внешний вывод программы в OCaml? Или, лучше, OCaml с Lwt?

Спасибо.

Ответ 1

Вы хотите Unix.open_process_in, который описан на стр. 388 руководства по системе OCaml версии 3.10.

Ответ 3

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

Ответ 4

Есть много примеров на PLEAC.

Ответ 5

Вы можете использовать стороннюю библиотеку 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, который возвращает строку "chomped" (новая строка удалена) команды "uname". В качестве второго примера

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.