如何使用反斜杠保护 \input shell 命令参数

如何使用反斜杠保护 \input shell 命令参数

我想要\input"|..."调用一个 shell 命令并将其输出作为 LaTeX 代码使用。

具体来说,我想编写类似以下内容的代码:
\expandableShellCmdProtectCmdArgsWithBackslashes{echo}{2(3)}
并让它使用以下内容调用 shell:
echo \2\(\3\)
使用反斜杠转义所有“arg”字符。
原因是转义 shell 特殊字符,例如(

期望的结果是echo打印2(3)并作为 LaTeX 输入使用。

\str_map_inline:nn下面通过+进行的尝试\c_backslash_str失败了,在调用 shell 之前我期望反斜杠的所有位置都出现了奇怪的倾斜双引号符号,而且实际执行的 shell 命令不包含大多数所需的输入。

如何在\input命令的每个字符前添加反斜杠?

\documentclass[11pt]{article}

\begin{document}

\makeatletter
\newcommand{\expandableShellCmd}[1]{ \@@input"|#1"} % \input is not expandable
\makeatother

\ExplSyntaxOn
\NewDocumentCommand{\protectWithBackslashes}{m} { % prepends every character of the input with a backslash
  \str_map_inline:nn{#1}{\c_backslash_str##1}
}
\NewDocumentCommand{\expandableShellCmdProtectCmdArgsWithBackslashes}{mm} {% shell command, args
  % Pass the input string as a cmd to the shell, but prepend each char in the args with a backslash
  \exp_args:Ne\expandableShellCmd{#1~\protectWithBackslashes{#2}} % Fully expand the argument before invoking the shell
}
\ExplSyntaxOff

\expandableShellCmdProtectCmdArgsWithBackslashes{echo}{2(3)} % want to run in shell "echo \2\(\3\)" which produces output "2(3)"
% However, this produces PDF output:
% “2“(“3“)”
% and the console output shows that the shell command executed was (without quotes) "|echo "

\end{document}

答案1

用 定义的命令\NewDocumentCommand不会受到e-expansion 的影响;也\str_map_inline:nn具有相同的特性,因此调用\exp_args:Ne根本不会执行任何操作。

而且我认为您不需要担心可扩展性。

\documentclass{article}

\ExplSyntaxOn

\tl_new:N \l_fink_shell_output_tl

\NewDocumentCommand{\DoShellCommand}{O{}m}
 {
  \fink_shell_do:nn { #1 } { #2 }
 }

\NewExpandableDocumentCommand{\protectWithBackslashes}{m}
 { % prepends every character of the input with a backslash
  \fink_shell_addbackslash:n { #1 }
 }

\cs_new_protected:Nn \fink_shell_do:nn
 {
  \sys_get_shell:nnN { #2 } { #1 } \l_fink_shell_output_tl
  \tl_use:N \l_fink_shell_output_tl
 }
\cs_generate_variant:Nn \fink_shell_do:nn { ne }

\cs_new:Nn  \fink_shell_addbackslash:n
 {
  \str_map_function:nN { #1 } \__fink_shell_addbackslash:n
 }
\cs_new:Nn \__fink_shell_addbackslash:n
 {
  \c_backslash_str #1
 }

\NewDocumentCommand{\DoShellCmdProtectCmdArgsWithBackslashes}{mm}
 {% shell command, args
  % Pass the input string as a cmd to the shell, but prepend each char in the args with a backslash
  \fink_shell_do:ne {} {#1~\fink_shell_addbackslash:n {#2}} 
  % Fully expand the argument before invoking the shell
}
\ExplSyntaxOff

\begin{document}

\DoShellCmdProtectCmdArgsWithBackslashes{echo}{2(3)}

\end{document}

日志文件有

(|echo \2\(\3\))

相关内容