Каков правильный способ вызова внешней команды и сбора ее вывода в OCaml?
В Python я могу сделать что-то вроде этого:
os.popen('cmd').read()
Как я могу получить весь внешний вывод программы в OCaml? Или, лучше, OCaml с Lwt?
Спасибо.
Каков правильный способ вызова внешней команды и сбора ее вывода в OCaml?
В Python я могу сделать что-то вроде этого:
os.popen('cmd').read()
Как я могу получить весь внешний вывод программы в OCaml? Или, лучше, OCaml с Lwt?
Спасибо.
Вы хотите Unix.open_process_in, который описан на стр. 388 руководства по системе OCaml версии 3.10.
Для 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
, который возвращает строку "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.