【问题标题】:Collecting the output of an external command using OCaml使用 OCaml 收集外部命令的输出
【发布时间】:2010-02-06 22:20:23
【问题描述】:

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

在 Python 中,我可以这样做:

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

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

谢谢。

【问题讨论】:

    标签: unix ocaml


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      对于 Lwt,

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

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

      【讨论】:

        【解决方案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,它返回“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 库还定义了一些常用命令的接口,Rashell_Posix 中定义了一个很好的find 命令接口——顺便保证了 POSIX 的可移植性。

            【讨论】:

            • 这几天好像 rashell 可能已经死了?很不幸,它看起来很棒
            • @Ulrar 好吧,我不知道你所说的死是什么意思,但对我来说,它目前已经完成了它的工作。你在那里缺少什么?欢迎您开票! :)
            • 好吧,它似乎不再编译了,看起来它引用了 lwt.ppx,据我所知,它不再存在,被 lwt_ppx 取代。是不是 opam 中的版本太旧了?
            • @Ulrar 好吧,我没有关注 OCaml 和 Lwt 的最新发展,但也许我现在是时候赶上。 :) 如果你在 GitHub 上开一张票,你会得到一些消息,因为它是固定的。
            • 当然可以。已经有一个,但问题并不完全相同,所以我制作了一个新问题。我希望解决依赖问题可能会揭示 2017 年的另一个问题。谢谢!
            猜你喜欢
            • 2010-10-19
            • 2022-08-02
            • 2021-05-05
            • 1970-01-01
            • 1970-01-01
            • 2013-10-13
            • 1970-01-01
            • 1970-01-01
            • 2023-03-12
            相关资源
            最近更新 更多