15
$\begingroup$

I am running Mathematica 10.2 on an Ubuntu workstation. I would like to be able to evaluate a notebook through the command line, and save its final state so that I can launch evaluation remotely through ssh and then take the resulting output.

From the command line --help

$ mathematica --help
Usage:  /usr/local/Wolfram/Mathematica/10.2/SystemFiles/FrontEnd/Binaries/Linux-x86-64/Mathematica [options] [files]
Valid options:
    ...
    -ne (--notebookevaluate):  Evaluates the input notebooks
    ...

it seems an easy task. The -ne parameter should make Mathematica evaluate the input notebooks.

But I created a simple test notebook test.nb with the following content (UPDATED, see EDIT)

2 + 2

f[x_] := x^2

D[f[x], x]

Export["test.txt", Table[i,{i,1,10}]]

Plot[f[x],{x,-4,4}]

Export["plot.pdf",%]

with an obvious expected output.

Running mathematica -ne test.nb creates the test_out.nb in my home folder, meaning that the notebook has been evaluated, but the Output is missing.


EDIT SquareOne methods work in the sense that output is written to the notebook and the notebook file is saved.

I currently have a problem with each method.

  1. Method 1: auxiliary notebook. I cannot get commands that output to file, such as Export[], to work. If evaluated through Method 1 I get a $Failed , with no messages. I tried to redirect $Messages to stderr but it doesn't work neither. The Export[] command and $Messages redirection work correctly with Method 2.

  2. Method 2: script. Graphics is not rendered as Output in the notebook, i.e. for the before-last command I obtain the following

    Graphics[{{{}, {}, {Directive[Opacity[1.], RGBColor[0.368417, 0.506779, 0.709798], AbsoluteThickness[1.6]], Line[{{-3.999999836734694, 15.999998693877577}, {-3.997546256735669, 15.98037607474136}, ...
    

    but the exported graphics, i.e. last command, is the correct PDF file of the plot. The graphics is rendered correctly with Method 1, but is not exported to PDF.

EDIT 2 A workaround for Method 2 has been posted in this answer and consists in wrapping each graphics in CellPrint[ExpressionCell[Grahics[...], "Output"]], e.g.

CellPrint[ExpressionCell[Plot[f[x],{x,-4,4}], "Output"]]

A more direct solution would still be preferable, but at least this one works nicely. We can define a wrapper to be postfixed to the graphics command:

RenderGraphics = CellPrint[ExpressionCell[#, "Output"]]&
Plot[f[x],{x,-4,4}] // RenderGraphics

Thanks to GustavoDelfino for pointing this out.

$\endgroup$
  • 1
    $\begingroup$ A solution for the graphics rendering problem in Method 2 (-script approach) has actually been found few days before this post by @GustavoDelfino ! See NotebookEvaluate with InsertResults -> True from the command line $\endgroup$ – SquareOne Nov 12 '15 at 22:12
  • $\begingroup$ @SquareOne thanks for pointing this out! I confirm this fixes the problem, but of course one needs to wrap every expression involving graphics in CellPrint[] which could not be very practical. I'm wondering, may there be a way to programmatically (and transparently) wrap all the cells through the script? $\endgroup$ – Pincopallino Nov 13 '15 at 9:39
  • $\begingroup$ I actually found the CellPrint is not needed in 10.3. For 10.2 I just added //report at the end of every command and defined report as a CellPrint[ExpressionCell[#,"Output"]]& wrapper $\endgroup$ – Gustavo Delfino Nov 13 '15 at 12:52
  • $\begingroup$ @GustavoDelfino I have v10.3.0 on OSX and there is no graphics rendering for me with the -script approach ! What is your OS ? $\endgroup$ – SquareOne Nov 13 '15 at 13:09
  • $\begingroup$ @GustavoDelfino it is still needed in 10.3 under Linux. Thanks, the //report is a good idea to improve readability. $\endgroup$ – Pincopallino Nov 13 '15 at 19:53
8
$\begingroup$

Update

  • a very simple solution to the OP has been given in this very duplicate post: all the outputs (in particular graphics) are then correctly inserted in the evaluated notebook without the need to insert/modify the original notebook with special commands.

  • also, as asked in the comments, I added a way to monitor in real time the different kind of outputs in the evaluated notebook. In particular, all the regular output can be logged thanks to this nice workaround using $PrePrint.

1/ Here is a test notebook, ("mynotebook.nb"), based on the OP example (you can copy/paste the following in a single notebook cell):

2 + 2

f[x_] := x^2

Plot[f[x], {x, 0, 1}]

Export["m_plot.pdf", %]

f[3]

1/0

Print["Now a 10 sec. pause"]

Pause[10]

Print["print result: ", f[11]]

Export["m_test.txt", Table[i, {i, 1, 10}]]

Echo[1 + 1, "echo result: "]

D[f[x], x]

100 + 1

2/ Here is an example script ("myscript.m") to programmatically evaluate and save the notebook from the command line and also to monitor its different outputs in separate log files. Adjust the script to your needs and set the correct file paths:

outputlogfile = OpenWrite["m_output.log", FormatType -> OutputForm];
$PrePrint = (Write[outputlogfile, #]; #) &;

printlogfile = OpenWrite["m_print.log", FormatType -> StandardForm];
AppendTo[$Output, printlogfile];

messageslogfile = OpenWrite["m_messages.log", FormatType -> OutputForm];
AppendTo[$Messages, messageslogfile];

(* ------- Only these 2 lines are needed if no monitoring is needed *) 
SetOptions[First[$Output],FormatType->StandardForm];
UsingFrontEnd[NotebookEvaluate["mynotebook.nb",InsertResults->True]] 
(* ------- *)

Close[messageslogfile];$Messages=$Messages[[{1}]];
Close[printlogfile];$Output=$Output[[{1}]];
Close[outputlogfile];

3/ Then just run the previous script from the command line using the math kernel command line, for example in Mac OS:

/Applications/Mathematica.app/Contents/MacOS/MathKernel -script myscript.m

(Tested with MMA v11.1.1.0)

-> You won't see any output to the console : as expected all the results are directly inserted and saved in the notebook as if you had evaluated the notebook directly by hand. Also as requested in the script, the outputs are duplicated/redirected in real time (see the Pause command) to the given simple text log files which make it possible to monitor the evaluation. In particular, it is only possible to log the Print command outputs separately from the rest of the outputs. I was not able to log the Echo command ... but this seems to be the starting point.

Remark : with the new wolframscript command line (added in new MMA versions) the notebook outputs were not inserted inside of it (only the Echo , the 1/0 error message and the last command output (100+1 -> 101) were inserted). The Print outputs were also redirected to the console.



Previous

I get the same behaviour than your ("no output") with OSX. I did not even succeed to export some expressions to a file from this notebook (by inserting extra code with Put[...] or Save[...])...

However, I've found 2 very simple alternatives using:

NotebookEvaluate["yourPathTo/test.nb", InsertResults -> True]

(Of course remove the command NotebookSave[EvaluationNotebook[], "test_out.nb"] from your test.nb for the following tests).

1. Notebook approach

  • put the previous NotebookEvaluate[...] command in a new notebook ("my.nb")
  • quit mathematica (later i get segmentation fault if I forget !)
  • run from the command line : mathematica -ne my.nb
    (on OSX /Applications/Mathematica.app/Contents/MacOS/Mathematica -ne my.nb)

Your test.nb notebook has been evaluated, the results were inserted inside it, and it was automatically saved. This means you loose your initial "template" test.nb, so be careful to backup it first !

2. Script approach

  • put UsingFrontEnd[NotebookEvaluate[...]] command in a text file ("my.m")
  • run from the command line the math kernel : math -script my.m
    (on OSX /Applications/Mathematica.app/Contents/MacOS/MathKernel -script my.m)

Your test.nb notebook has been modified the same way than in the previous approach.


Remark: I was not able to use the math kernel approach with the -noprompt option. For example on OSX:

echo 'UsingFrontEnd[NotebookEvaluate["~/test.nb", InsertResults -> True]]' |
 /Applications/Mathematica.app/Contents/MacOS/MathKernel -noprompt

just hangs indefinetely ... ? The same command works if i remove the -noprompt but this starts an interactive mode which is not the goal here.

$\endgroup$
  • $\begingroup$ Method 1 works great! With Method 2 I have a FrontEndObject::notavail error, but I don't care as long as Method 1 works. However, there seems to be a problem with file output as I can't get Export[] to work, see edit. $\endgroup$ – Pincopallino Nov 4 '15 at 10:26
  • 1
    $\begingroup$ @Pincopallino For method 2, are you sure you wrapped the NotebookEvaluate command in UsingFrontEnd as indicated ? $\endgroup$ – SquareOne Nov 4 '15 at 10:30
  • $\begingroup$ oh my, I wrote UsingFrontend instead of UsingFrontEnd. Now method 2 works perfectly and moreover Export[] works as expected. Now I wonder why it doesn't work with method 1 $\endgroup$ – Pincopallino Nov 4 '15 at 10:38
  • $\begingroup$ @Pincopallino I confirm that with method 1 I cannot "export" any file, and that it works for method 2. Also, I tested the notebook with Graphics ... only method 1 works ! I will edit my post to mention that and try to investigate more ... $\endgroup$ – SquareOne Nov 4 '15 at 10:45
  • $\begingroup$ it's true, it doesn't work with Graphics, in the sense that the output is not the rendered graphics. However, if the graphics object is exported to file it works correctly. Probably, getting method 1 to work would solve all problems. I will keep investigating as well. $\endgroup$ – Pincopallino Nov 4 '15 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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