2
$\begingroup$

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.

$\endgroup$
2

1 Answer 1

5
$\begingroup$

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.

$\endgroup$
6
  • $\begingroup$ 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. $\endgroup$
    – Sumit
    May 14, 2014 at 15:46
  • $\begingroup$ @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. $\endgroup$
    – arnd
    May 15, 2014 at 7:51
  • $\begingroup$ 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). $\endgroup$
    – Sumit
    May 19, 2014 at 19:56
  • $\begingroup$ @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. $\endgroup$
    – arnd
    May 20, 2014 at 8:53
  • $\begingroup$ @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. $\endgroup$
    – arnd
    May 20, 2014 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.