Friday, April 30, 2010

Haskell Tip: Redirect stdout in Haskell

Have you ever wanted to make sure that a call to a library cannot print anything to stdout? The following does this except that it redirects stdout globally and not just across a library call. This should be doable, but I haven't needed it yet.
import GHC.IO.Handle   -- yes, it's GHC-specific
import System.IO

main = do
  stdout_excl <- hDuplicate stdout
  hDuplicateTo stderr stdout  -- redirect stdout to stderr
  
  putStrLn "Hello stderr" -- will print to stderr
  hPutStrLn stdout_excl "Hello stdout" -- prints to stdout
The above code first creates a new handle to the standard output resource using hDuplicate. The call to hDuplicateTo redirects any output to the Haskell handle stdout to go to the handle stderr. The Haskell handle stdout_excl is now our only handle to the standard output resource.