Pregunta

How can you redirect the standard output in OCaml ? I tried Format.set_formatter_out_channel but it doesn't seem to work. When I use printf afterwards, the text is still printed on the screen, and the file I created remains empty.

¿Fue útil?

Solución

The reason your experiment failed is that Printf.printf doesn't use the output channel of the Format module. The Format module is for pretty-printing, a fairly elaborate task. The Printf.printf function writes formatted data to the standard output (a C-style printf).

Do you really want to redirect standard output, or do you just want to write to a specific channel? To write to a channel oc you can just use

Printf.fprintf oc ...

rather than

Printf.printf ...

Doing redirection is a different thing. You can do it with Unix.dup2. Here's an example session that shows how to do it:

$ 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

Since this is changing low-level file descriptors behind the back of the OCaml I/O system, I'd be a little careful. As a quick hack it's fantastic--I've done it many times.

Update

Here's a version of the above code that redirects standard output temporarily, then puts it back where it was before.

$ 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top