注意:\input
不可扩展:为什么 \input 不可扩展?
然而\@@input
是。
目标是\@@input
从 shell 调用生成一些文本,通过以下方式获得\sys_get_shell:nnN
(有关如何操作,请egreg
参阅Write18:捕获 shell(脚本)输出作为命令/变量?)。
例如,shell 调用可能会产生输出\A\B\C\D
,我们希望将其插入到输入流中,因为文档定义了这些命令。
的结果\sys_get_shell:nnN
保存到变量中\result
,因此我们希望将该变量(expanded)传递给\@@input
。我们可以在调用之前
使用\exp_args:Ne\@@input{\result}
expand 。\result
\@@input
为了\@@input
做某事,您可以从文件中读取\@@input"my_file"
,也可以从 shell 命令的输出中读取:\@@input"|my_shell_command_here"
。
为了避免写入临时文件,我想使用 shell|
选项。
因此我们可以只|echo \result
。
但是,这不会产生预期的效果:在 shell 命令中,\
是转义字符,因此如果它包含(或其他 shell 特殊标记,如) echo
,则不会打印出我们想要的内容。\
(
我的下一个想法是使用 来保护传递给 shell 的每个字符\
,这似乎会产生所需的结果。如果是\result
= \A\B\C\D
,我们将传递\\\A\\\B\\\C\\\D
给 shell:
$ echo \\\A\\\B\\\C\\\D
\A\B\C\D
为了执行这种映射,我们可以使用\tl_analysis_map_inline:nn
(或\str_map_inline:nn
?) 在每个标记前面添加\
:
\tl_analysis_map_inline:nn{\result}{\c_backslash_str#1}
为了举例子,我们假设 shell 输出是:
hi
ho
\A\B\C\D
\A\B\C\D
完整的尝试如下:
\documentclass[11pt]{article}
\begin{document}
\newcommand{\A}{myA}
\newcommand{\B}{myB}
\newcommand{\C}{myC}
\newcommand{\D}{myD}
\makeatletter
\newcommand{\expandableinput}[1]{ \@@input #1 }
\makeatother
\ExplSyntaxOn
\NewDocumentCommand{\inputfromecho} {m} {
\expandableinput{"|echo~hi~&&~echo~ho~&&~echo~#1~&&~echo~#1"}
}
\NewDocumentCommand{\inputexpand} {m} {
% Force expand #1 before calling \@@input
\exp_args:Ne\inputfromecho{#1}
}
\NewDocumentCommand{\sampleShellOutput} {} {
\tl_analysis_map_inline:nn{ABCD}{\c_backslash_str##1}
}
\NewDocumentCommand{\backslashProtectedShellOutput} {} {
\exp_args:Ne\tl_analysis_map_inline:nn{\sampleShellOutput}{\c_backslash_str##1}
}
\ExplSyntaxOff
Shell output:\\
\sampleShellOutput
Shell output as input:\\
\inputexpand{\backslashProtectedShellOutput}
\end{document}
但是,这会在最后 2&
秒产生错误,并持续输出:
Shell output:
“A“B“C“D
Protected shell output:
““A“B“C“D
Shell output as input:
hi ho
““A“B“C“D echo ““A“B“C“D”
我们还从控制台日志中看到实际运行的 shell 命令是:
|echo hi && echo ho && echo
尽管我们预期运行:
|echo hi && echo ho && echo \\\A\\\B\\\C\\\D && echo \\\A\\\B\\\C\\\D
好像\
打印为"
,并且匹配"
以完成\@@input
,从而在中间切断shell命令。
如果不"
包围 shell 命令,\@@input
似乎会在第一个空格处停止解析 shell 命令。
有没有更简单(或任何成功)的方法来输入变量的完全展开的内容\input
?
答案1
问题中的扩展控件的意图并不十分清楚。我认为扩展的参数\input
和扩展返回的标记之间存在混淆。
如果将以下内容保存为testcmd
echo hi
echo ho
echo '\A\B\C\D'
echo '\A\B\C\D'
并使其可执行;
$ chmod a+x ./testcmd
(在 Windows 上你可以制作一个等效的testcmd.bat
)
然后在命令行上该命令有建议的输出:
$ ./testcmd
hi
ho
\A\B\C\D
\A\B\C\D
因此,要从乳胶中调用它,请使用
pdflatex --shell-escape file
哪里file.tex
\documentclass[11pt]{article}
\makeatletter
\def\shellcmd#1{\@@input"|#1" }
\makeatother
\begin{document}
\newcommand{\A}{myA}
\newcommand{\B}{myB}
\newcommand{\C}{myC}
\newcommand{\D}{myD}
\shellcmd{./testcmd}
\end{document}
制作
上面回答了标题中关于解释 shell 调用的输出的问题,但在评论中您指出了一个不相关的问题,将 tex 标记列表解释为 tex 输入,我如下所示。
\documentclass{article}
\newcommand{\A}{myA}
\newcommand{\B}{myB}
\newcommand{\C}{myC}
\newcommand{\D}{myD}
\edef\var{hi
ho
\string\A\string\B\string\C\string\D
\string\A\string\B\string\C\string\D
}
\begin{document}
\verb|\var| character tokens: \texttt{\var}
Re-interpret \verb|\var| as \TeX: \scantokens\expandafter{\var}
\end{document}