4.2.4 执行程序

4.2.4 执行程序

考虑以下 LuaTeX 文件。

#################################
foo.tex
#################################
\documentclass[12pt]{article}
\usepackage{filecontents}
\begin{filecontents*}{foo.lua}
  assert(os.execute([[ latexmk x.tex ]]) == 0)
\end{filecontents*}
\begin{filecontents*}{x.tex}
\documentclass[12pt]{article}
\begin{document}
X
\end{document}
\end{filecontents*}
\begin{document}
\directlua{foo = require "foo.lua"}
\end{document}
#################################

如果我运行 Lua 代码,断言就会失败。

lua5.3 foo.lua
Latexmk: This is Latexmk, John Collins, 25 October 2018, version: 4.61.
Latexmk: All targets (x.dvi) are up-to-date
lua5.3: foo.lua:7: assertion failed!
stack traceback:
        [C]: in function 'assert'
        foo.lua:7: in main chunk
        [C]: in ?

但是如果我使用“luatex”运行 LuaTeX 代码,我仍然会收到断言错误:

lualatex foo.tex
This is LuaTeX, Version 1.10.0 (TeX Live 2019/Debian)
 restricted system commands enabled.
(./foo.tex
LaTeX2e <2018-12-01>

luaotfload | main : initialization completed in 0.086 seconds
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2018/09/03 v1.4i Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo))
(/usr/share/texlive/texmf-dist/tex/latex/filecontents/filecontents.sty)

LaTeX Warning: Overwriting file `./foo.lua'.

LaTeX Warning: Overwriting file `./x.tex'.

(./foo.aux)./foo.lua:7: assertion failed!
stack traceback:
        [C]: in function 'assert'
        ./foo.lua:7: in main chunk
        [C]: in function 'require'
        [\directlua]:1: in main chunk.
l.19 \directlua{foo = require "foo.lua"}

但是,如果我使用“luatex -shell-escape”,就不会出现断言错误。

lualatex -shell-escape foo.tex
This is LuaTeX, Version 1.10.0 (TeX Live 2019/Debian)
 system commands enabled.
(./foo.tex
LaTeX2e <2018-12-01>

luaotfload | main : initialization completed in 0.094 seconds
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2018/09/03 v1.4i Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo))
(/usr/share/texlive/texmf-dist/tex/latex/filecontents/filecontents.sty)

LaTeX Warning: Overwriting file `./foo.lua'.

LaTeX Warning: Overwriting file `./x.tex'.

(./foo.aux)Latexmk: This is Latexmk, John Collins, 25 October 2018, version: 4.61.
Latexmk: All targets (x.dvi) are up-to-date
 (./foo.aux))
 384 words of node memory still in use:
   2 hlist, 1 vlist, 1 rule, 2 glue, 3 kern, 1 glyph, 5 attribute, 44 glue_spec
, 5 attribute_list, 2 write nodes
   avail lists: 2:7,3:1,4:1,5:4,7:1,9:1

warning  (pdf backend): no pages of output.
Transcript written on foo.log.

我不明白这种行为的原因。如果我将这 assert一行替换为

assert(os.execute([[ foobar ]]) == 0)

例如,无论哪种方式我都会看到断言错误。

编辑:我发现原因是os.execute返回不同的值,具体取决于是否-shell-escape传递给 LuaTeX。这可能在某处有记录,但令我感到惊讶。

那么,这是什么原因造成的?如果有记录的话,记录在哪里?为了记录,我使用

x, y, z = os.execute([[ latexmk x.tex ]])
print(string.format("execute return values are %s, %s, %s", x, y, z)) 

而且它们看起来(没有-shell-escape

执行返回值为 nil,通过 shell_escape='p' 禁用命令执行,nil

-shell-escape

执行返回值为 0, nil, nil

直接来自 Lua 的值是

执行返回值为 true、exit、0

答案1

Lua 后端遵循--shell-escape相同的方式\write18。手册中也有记录。

4.2.4 执行程序

为了与 TeX Live 中的其他类 TeX 程序保持一致,两个 Lua 函数 os.executeio.popen以及下面介绍的两个新函数os.exec和 都采用了和/或 的值。每当运行 LuaTeX 并假定其意图是排版文档时(我们的意思是它被称为 ,而不是,并且 没有给出 命令行选项),它只会在匹配变量或它们(参见第 10.4 节)对应项允许执行请求的系统命令时运行上述四个函数。在 LuaTeX 的“脚本解释器”运行中,这些设置不起作用,所有四个函数都具有其原始含义。os.spawnshell_escapeshell_escape_commandsluatextexlua--luaonlytexmf.cnftexconfig

事实上,LuaTeX os.execute(和io.popen)与普通 Lua 的变体有着根本的不同。你可以比较os_execute比较LuaTeX与来自普通的 Lua

相关内容