Как оценить ноутбук из командной строки?
Как мы можем вычислить ноутбук Mathematica из командной строки (т.е. при запуске ядра в режиме командной строки)?
Предположим, что мы работаем на удаленной машине. Я знаю, что можно преобразовать ноутбук в m файл и оценить его, но мне любопытно, можно ли это сделать непосредственно с помощью ноутбука.
Это то, что у меня есть до сих пор:
Во-первых, нам нужно запустить безголовый X-сервер на удаленной машине Linux, поэтому перед ним можно запустить интерфейс (и откройте ноутбук). Пропустите этот шаг, если вы работаете на локальной машине.
Xvfb :1 &
export DISPLAY=:1
После этого я запустил ядро Mathematica (math
) и сделал следующее.
Необходимо использовать UsingFrontEnd
, потому что для открытия ноутбука требуется передний конец. test.nb имеет единственную ячейку ввода, содержащую a=1
.
In[1]:= [email protected]["test.nb"]
Out[1]= -NotebookObject-
Попытавшись оценить ноутбук, видимо, я получаю dialog, и мне нужно использовать Return[]
для возврата. Я не уверен, почему строка ввода начинает отсчет с 1 снова (новое ядро запускалось передним концом?). Обратите внимание, что a
не получило значения.
In[2]:= [email protected][nb]
In[1]:= a
Out[1]= a
In[2]:= Return[]
Out[2]= a
После возвращения из диалога a
все еще не имеет значения.
In[3]:= a
Out[3]= a
Ответы
Ответ 1
Это в 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];
[email protected]@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];
]
Ответ 2
Это частичный ответ на ваш вопрос. Следующий код открывает ноутбук, назначает ему
Ядро "Тест", оценивает ноутбук в этом ядре, ждет завершения оценки и
сохраняет оцененный ноутбук. Это не приводит к определению a
в локальном ядре командной строки.
Ожидается, что оценки ядра будут завершены в записной книжке:
NotebookPauseForEvaluation[nb_] := Module[{},
While[ NotebookEvaluatingQ[nb], Pause[.25] ] ]
Это проверяет, находится ли какая-либо ячейка в записной книжке по-прежнему:
NotebookEvaluatingQ[nb_]:=Module[{},
SelectionMove[nb,All,Notebook];
[email protected]@Map["Evaluating"/.#&,Developer`CellInformation[nb]]
]
Это просто диагностическое сообщение, когда вы пытаетесь переопределить ядро как "Тест":
AddTestEvaluator::exists = "Evaluator `1` is already defined, but has a definition that is `2` and not the expected `3`.";
Это код для добавления оценщика, такого как "Тест" к интерфейсу:
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]
]
]
Наконец, это код для оценки ноутбука под ядром "Тест" и сохранения оцененного ядра:
UsingFrontEnd[
AddTestEvaluator["Test"];
nb = NotebookOpen["test.nb"];
SetOptions[nb,Evaluator->"Test"];
SelectionMove[nb,All,Notebook];
SelectionEvaluate[nb];
NotebookPauseForEvaluation[nb];
NotebookSave[nb]
]
Я все еще ищу решение для вашей полной проблемы (имея a
, определенный в локальной команде
линейное ядро).