在命令行上传递带有不平衡引号的文本作为参数

在命令行上传递带有不平衡引号的文本作为参数

我想转发第三方调度程序运行的作业的作业输出。调度程序允许我将输出插入到命令中,例如:

python script.py --job-output '{joboutput}'

其中{joboutput}成为调度程序转发的原始作业输出。

我遇到的问题是作业输出可以包含不平衡的单引号和双引号(以及特殊字符(,如|等),因此将作业输出用单引号或双引号括起来都不起作用。

我浏览了许多类似的问题,但没有发现涵盖这个确切场景的问题。我将非常感谢任何建议。非常感谢!

答案1

如果该命令行由调度程序预处理,然后将其发送到 shell 执行(例如,虽然sh -c),在用实际文本进行简单的文本替换之后{joboutput},那么您所要求的实际上无法完成。无论如何,不​​只在一根线上。

可以将任意(NUL 终止)字符串作为命令行参数传递(无论如何都达到某个最大长度),但在 shell 命令行上插入字符串需要遵循 shell 的语法/引用规则。

基本上,shell 有双引号、单引号和反斜杠转义。在双引号内,您需要通过在反斜杠前面添加一些字符来转义它们,因此您不能在其中放置任意字符串。在单引号内,您不需要转义任何其他内容,但单引号本身需要特殊处理。通常的方法是将引号替换为'\'',这只是关闭带引号的字符串,插入转义的单引号,然后重新打开带引号的字符串。无论如何,有些角色需要特殊对待,这是没有办法的。必须是这样,因为 shell 需要某种方法来确定带引号的字符串结束的位置。

因此,如果您使用"{joboutput}"and{joboutput}替换为包含"$\的内容`,它就会损坏;如果你使用'{joboutput}'and{joboutput}替换为包含 a 的东西',它就会崩溃。

某些语言可能有更详细的引号,例如 Python 的"""/ ''',这可能会有所帮助,因为它们允许偶尔使用单独的引号或引号对,但当然仍然不完全通用,因为输出可能包含相同的"""'''

但外壳没有这些。最接近的可能是here-docs,它们由自由选择的分隔线。这将有助于嵌入几乎任意字符串,但它确实需要能够传递多行,并且相当麻烦。

如果可以使用多行命令,则如果{joboutput}被任何不END_OF_JOB_OUTPUT禁止解析与命令替换中的here-doc相关的shell中的错误的任何内容替换,则应该可以工作。您可以将此处的文档分隔符更改为任何其他字符串,该字符串不太可能出现在输出中。但是,由于数据在这里经过命令替换,因此其中的任何尾随换行符都会丢失。

out=$(cat <<'END_OF_JOB_OUTPUT'
{joboutput}
END_OF_JOB_OUTPUT
)
python script.py --job-output "$out"

或者不在命令替换中嵌套此处文档:

exec 9<<'END_OF_JOB_OUTPUT'
{joboutput}
END_OF_JOB_OUTPUT
out=$(cat <&9)
exec 9<&-

printf "%s\n" "$out"

如果调度程序能够直接启动该命令,而不涉及 shell,我们就不需要关心 shell 的语法。调度程序只需要有一些智能来显式传递script.py--job-output作业输出作为不同的参数。但我们不知道它是否可以做到这一点。 (此外,在这种情况下,您不会在占位符周围使用引号。)

另一种比上面的 shell 恶作剧更容易的方法是通过环境变量或文件传递字符串(如果调度程序支持的话)。

相关内容