重定向标准输出OCaml

重定向标准输出OCaml,ocaml,redirectstandardoutput,Ocaml,Redirectstandardoutput,如何在OCaml中重定向标准输出? 我尝试了格式化。设置格式化程序\u输出\u频道,但似乎不起作用。当我后来使用printf时,文本仍然打印在屏幕上,我创建的文件仍然是空的。实验失败的原因是printf.printf没有使用格式模块的输出通道。格式模块用于相当精细的打印任务。Printf.Printf函数将格式化数据写入标准输出(C样式Printf) 您真的想重定向标准输出,还是只想写入特定通道?要写入频道oc,只需使用 Printf.fprintf oc ... 而不是 Printf.pri

如何在OCaml中重定向标准输出?
我尝试了
格式化。设置格式化程序\u输出\u频道
,但似乎不起作用。当我后来使用printf时,文本仍然打印在屏幕上,我创建的文件仍然是空的。

实验失败的原因是printf.printf没有使用格式模块的输出通道。格式模块用于相当精细的打印任务。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

谢谢我希望能够从标准输出切换到文件,而不必将所有printfs更改为fprintfs。我猜是懒惰(当我可以找到并替换时——但我做了大量的Printf,并且必须在参数中为每个函数提供输出通道…。@Sheeft将
Printf.Printf
改为
Format.Printf
,并享受新的超级功能:-)如果你愿意,你可以使用实际的重定向。我将扩展我的答案。有没有一种简单的方法可以在一段时间后回到标准输出?例如,如果我只想暂时重定向一个函数的输出,然后恢复正常操作,那么使用Unix
dup
执行这些操作并不困难。我会更新我的答案。