Sza*_*lcs 19 wolfram-mathematica mathematica-frontend
我们如何从命令行评估Mathematica笔记本(即在命令行模式下运行内核时)?
假设我们正在使用远程计算机.我知道有可能将笔记本转换为m文件,并对其进行评估,但我很好奇是否有可能直接使用笔记本进行此操作.
这是我到目前为止:
首先,我们需要在远程Linux机器上启动无头X服务器,因此前端可以在那里运行(并打开笔记本电脑).如果您正在使用本地计算机,请跳过此步骤.
Xvfb :1 &
export DISPLAY=:1
Run Code Online (Sandbox Code Playgroud)
在此之后我开始使用Mathematica内核(math)并执行以下操作.
这是必要的,UsingFrontEnd因为打开笔记本需要一个前端.test.nb有一个包含的输入单元格a=1.
In[1]:= nb=UsingFrontEnd@NotebookOpen["test.nb"]
Out[1]= -NotebookObject-
Run Code Online (Sandbox Code Playgroud)
在尝试评估笔记本之后,显然我得到了一个对话框,我需要Return[]用来返回.我不确定为什么输入行从1再次开始计数(前端启动了一个新内核?)注意,a没有获得值.
In[2]:= UsingFrontEnd@NotebookEvaluate[nb]
In[1]:= a
Out[1]= a
In[2]:= Return[]
Out[2]= a
Run Code Online (Sandbox Code Playgroud)
从对话框返回后,a仍然没有值.
In[3]:= a
Out[3]= a
Run Code Online (Sandbox Code Playgroud)
Arn*_*ing 11
这是对您的问题的部分答案.下面的代码打开一个笔记本,为它分配一个"Test"内核,评估该内核中的笔记本,等待评估完成并保存评估的笔记本.但它不会导致a在本地命令行内核中定义.
这等待内核评估在笔记本中完成:
NotebookPauseForEvaluation[nb_] := Module[{},
While[ NotebookEvaluatingQ[nb], Pause[.25] ] ]
Run Code Online (Sandbox Code Playgroud)
这将检查笔记本中的任何单元格是否仍在评估中:
NotebookEvaluatingQ[nb_]:=Module[{},
SelectionMove[nb,All,Notebook];
Or@@Map["Evaluating"/.#&,Developer`CellInformation[nb]]
]
Run Code Online (Sandbox Code Playgroud)
当您尝试重新定义像"Test"这样的内核时,这只是一条诊断消息:
AddTestEvaluator::exists = "Evaluator `1` is already defined, but has a definition that is `2` and not the expected `3`.";
Run Code Online (Sandbox Code Playgroud)
这是向前端添加评估器的代码,例如"Test":
AddTestEvaluator[evaluator_String] := Module[
{evaluatornames, testevaluator},
evaluatornames = EvaluatorNames /. Options[$FrontEnd, EvaluatorNames];
testevaluator = evaluator -> {"AutoStartOnLaunch" -> False};
Which[
MemberQ[evaluatornames, evaluator -> {"AutoStartOnLaunch" -> False}],
Null,
MemberQ[evaluatornames, evaluator -> _],
Message[AddTestEvaluator::exists,
evaluator,
evaluator /. (EvaluatorNames /. Options[$FrontEnd, EvaluatorNames]),
{"AutoStartOnLaunch" -> False}
],
True,
AppendTo[evaluatornames, testevaluator];
SetOptions[$FrontEnd, EvaluatorNames -> evaluatornames]
]
]
Run Code Online (Sandbox Code Playgroud)
最后,这是在"Test"内核下评估笔记本并保存评估内核的代码:
UsingFrontEnd[
AddTestEvaluator["Test"];
nb = NotebookOpen["test.nb"];
SetOptions[nb,Evaluator->"Test"];
SelectionMove[nb,All,Notebook];
SelectionEvaluate[nb];
NotebookPauseForEvaluation[nb];
NotebookSave[nb]
]
Run Code Online (Sandbox Code Playgroud)
我仍然在寻找一个完整问题的解决方案(a在本地命令行内核中定义).
Rol*_*tig 10
这是在Windows上,使用Arnouds很好的工作,只是添加简单的旧MathLink(非常慢btw ...):
link = LinkCreate["8000", LinkProtocol -> "TCPIP"];
UsingFrontEnd[
NotebookPauseForEvaluation[nb_] := Module[{},
While[ NotebookEvaluatingQ[nb], Pause[.25] ] ];
NotebookEvaluatingQ[nb_]:=Module[{},
SelectionMove[nb,All,Notebook];
Or@@Map["Evaluating"/.#&,Developer`CellInformation[nb]]
];
nb = NotebookOpen["G:\\mma\\test.nb"];
SelectionMove[nb, Before, Notebook];
NotebookWrite[nb, Cell["Link = LinkConnect[\"8000\", LinkProtocol -> \"TCPIP\"]", "Input"]];
SelectionMove[nb, After, Notebook];
NotebookWrite[nb, Cell["LinkWrite[Link, a]", "Input"]];
SelectionMove[nb, All, Notebook];
SelectionEvaluate[nb];
a = LinkRead[link];
Print["a = ",a];
]
Run Code Online (Sandbox Code Playgroud)