重定向标准输出OCaml

时间:2013-10-22 20:38:47

标签: ocaml redirectstandardoutput

如何在OCaml中重定向标准输出? 我试过Format.set_formatter_out_channel,但它似乎不起作用。当我之后使用printf时,文本仍然会打印在屏幕上,我创建的文件仍为空。

1 个答案:

答案 0 :(得分:11)

您的实验失败的原因是Printf.printf不使用Format模块的输出通道。 Format模块用于漂亮打印,这是一项相当复杂的任务。 Printf.printf函数将格式化数据写入标准输出(C样式printf)。

您真的想要重定向标准输出,还是只想写入特定频道?要写入频道oc,您只需使用

即可
Printf.fprintf oc ...

而不是

Printf.printf ...

进行重定向是另一回事。您可以使用Unix.dup2执行此操作。这是一个示例会话,展示了如何执行此操作:

$ cat redirected
cat: redirected: No such file or directory

$ cat redir.ml
let main () =
    let newstdout = open_out "redirected" in
    Unix.dup2 (Unix.descr_of_out_channel newstdout) Unix.stdout;
    Printf.printf "line of text\n";
    Printf.printf "second line of text\n"

let () = main ()

$ ocamlopt -o redir unix.cmxa redir.ml
$ ./redir

$ cat redirected
line of text
second line of text

由于这会改变OCaml I / O系统背后的低级文件描述符,我会有点小心。作为一个快速的黑客,它太棒了 - 我已经做了很多次。

<强>更新

以上代码的版本暂时重定向标准输出,然后将其放回原来的位置。

$ cat redirected
cat: redirected: No such file or directory
$
$ cat redir.ml
let main () =
    let oldstdout = Unix.dup Unix.stdout in
    let newstdout = open_out "redirected" in
    Unix.dup2 (Unix.descr_of_out_channel newstdout) Unix.stdout;
    Printf.printf "line of text\n";
    Printf.printf "second line of text\n";
    flush stdout;
    Unix.dup2 oldstdout Unix.stdout;
    Printf.printf "third line of text\n";
    Printf.printf "fourth line of text\n"

let () = main ()
$
$ ocamlopt -o redir unix.cmxa redir.ml
$ ./redir
third line of text
fourth line of text
$
$ cat redirected
line of text
second line of text