使用变量的值(由 shell 调用产生)作为 `\input`

使用变量的值(由 shell 调用产生)作为 `\input`

注意:\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}

在此处输入图片描述

相关内容