# How to record all the output (including error messages) of a mathematica script in a file?

Is it possible to record all the output of a Mathematica script to a file? I am looking for the Mathematica equivalent of fortran ./a.out > out.dat which record all the output string to the file out.dat.

Using OpenWrite[] and WriteString[] can record only the part I can specify but not the error messages which also can appear during execution. For example consider the script test.m

Print@"Start";
x=1/0;
Print@x;
Quit[];


If you run math -script test.m it will produce a message about encountering 1/0 apart from the string "Start" and "ComplexInfinity" due to the Print. I want to record all these messages in a file. Is it possible?

Clarification

When you run a script in terminal it produces different messages, both user defined (with Print) or machine generated (like error messages). In a note book they are automatically recorded. But when running the script in background in a remote machine, it is not possible to keep track of all the messages. So I am looking for a way to record them in a file so that I can get an idea of the progress at any instance by looking at that file.

-
The title suggests you want everything outputted but the body reads more like you just want the error messages? these might be useful posts: mathematica.stackexchange.com/questions/29235/… mathematica.stackexchange.com/questions/20367/… mathematica.stackexchange.com/questions/31099/… –  Mike Honeychurch May 14 '14 at 10:34
thanks @MikeHoneychurch. The main idea is to catch all the messages the execution can generate. When you are running a job in another machine in background, you can keep a track on the progress by looking at the output. I am sorry if the example is misleading. –  Sumit May 14 '14 at 11:07

For this kind of "logging" in SubKernels for example I use the following code:

oldoutput = $Output; (* store$Output *)
oldmessages = $Messages; (* same for$Messages *)
CheckAbort[
logstream = OpenWrite["yourlog.log"];
$Output = {logstream}; (* redirect$Output *)
AppendTo[$Messages, logstream]; (* add the logfile as an additional destination for$Messages *)
(* your code *)
,
AbortProtect[
Close[logstream];
$Output = oldoutput; (* restore$Output *)
$Messages = oldmessages; (* restore$Messages *)
];
];
Close[logstream];
$Output = oldoutput; (* restore$Output *)
$Messages = oldmessages; (* restore$Messages *)


This code redirects the output (things that were Print[]ed for example) and the messages ("Division by zero" etc) to the file "yourlog.log" and restores the old output channels after completion of the calculation.

The construction with CheckAbort[] is used to restore output channels in case of an Abort[] - either by your code or by the user.

PS: Sorry about the obvious comments. There seems to be a bug in the SE syntax highlighting code that breaks indentation when there is an unmatched number of dollar signs on a line.

-
thanks @arnd . But I think there is something wrong. The code is running fine. But when I am executing the job in background like math -script test.m & it is not returning anything. can you check whether it is a bug or my fault perhaps. –  Sumit May 14 '14 at 15:46
@Sumit: Do you mean that the log file is empty or that output (e.g. from Print[]) doesn't reach your frontend? The first option I can't confirm. The second option is intentional since I wanted to avoid the clutter of several subkernels writing to my frontend at the same time. If you want to see the output in your frontend, you can use AppendTo[...] for $Output as well, similar to what I did for $Messages. Note that messages should reach your frontend with the code in its original form. –  arnd May 15 '14 at 7:51
Hi @arnd. Sorry for the delay. When I use math -script test.m & it is not producing any file at all. I replace (your code) by Print@"Start"; x=1/0; Print@x; (Quit[];) and run math -script test.m & from terminal. when I check for the background job with bg, I find that the job is stopped ([Stopped math -script test.m]) and there is no yourlog.log file. btw I am using Mathematica 9.0 for Linux x86 (64-bit). –  Sumit May 19 '14 at 19:56
@Sumit: This seems to be related to starting the script in the background (the & at the end of your command). It appears that Mathematica - for some reason - tries to open the standard input for reading even if you specify a script. If you start Mathematica in Background then, your shell will suspend the job. Same goes for output (the messages are only copied to the log file but also reach the console). You have two options: 1) Don't run Mathematica in the background. (Is it really necessary?) 2) Redirect input and output to /dev/null. I would recommend option 1. –  arnd May 20 '14 at 8:53
@Sumit: Another comment concerning your code: You don't have to execute Quit[]; at the end. Your script will terminate if it reaches the end. If you really want to include that command, you should put it at the very end of my code. –  arnd May 20 '14 at 8:56