如何将整个命令存储在 bash 变量中并通过有限的分词逐字执行它们?

How to store entire commands in bash variables and exec them literally with limited word splitting?

我有很多行如下,其中前缀总是相同的,实际执行的命令不同。

ssh -F "${SSH_CFG}" "${SSH_DST}" "[...]"
ssh -F "${SSH_CFG}" "${SSH_DST}" "[...]"
ssh -F "${SSH_CFG}" "${SSH_DST}" "[...]"

为了不再赘述,我想使整个前缀也成为一个变量,如下例所示:

SSH_CMD="ssh -F ""${SSH_CFG}"" ""${SSH_DST}"""

${SSH_CMD} "[...]"
${SSH_CMD} "[...]"
${SSH_CMD} "[...]"

只要空格不用作路径或选项的一部分,这就有效,因为根据我的理解,上面使用的前缀会受到 shell 的分词。当然,出于各种原因,我有一些带空格的选项,这些选项需要按原样转发,作为一个参数。上面的例子不是这种情况,整个命令失败了。 OTOH,引用前缀也是错误的,因为在那种情况下,一个带有参数的命令将被视为一个文件并且找不到。所以下面的例子不起作用:

SSH_CMD="ssh -F ""${SSH_CFG}"" ""${SSH_DST}"""

"${SSH_CMD}" "[...]"
"${SSH_CMD}" "[...]"
"${SSH_CMD}" "[...]"

我想要的是一个像上面 SSH_CMD 一样的变量,其中包含一个已经用引号引起来的字符串来处理空格等,并且该字符串按原样用作前缀。虽然,在那种情况下,我仍然需要通过 shell 使用空格来区分命令和所有单独的参数进行某种程度的分词,但在这些参数中,不得发生分词以保留路径和带有空格的选项正确的。我找不到做后者的方法:无论我尝试什么,要么无法在分词中存活下来,要么像 "' 这样的字符被添加到路径和选项中,很可能是由于分词错误。

SSH_CMD="ssh -F ""${SSH_CFG}"" ""${SSH_DST}"""

${SSH_CMD} "[...]"
${SSH_CMD} "[...]"
${SSH_CMD} "[...]"

SSH_CMD="ssh -F ""${SSH_CFG}"" ""${SSH_DST}"""

ssh -F "${SSH_CFG}" "${SSH_DST}" "[...]"
ssh -F "${SSH_CFG}" "${SSH_DST}" "[...]"
ssh -F "${SSH_CFG}" "${SSH_DST}" "[...]"

那么,有什么方法可以使上面的示例完全正常工作吗?

谢谢!

定义函数,而不是变量。

ssh_cmd () {
    ssh -F "$SSH_CFG" "$SSH_DST" "$@"
}


ssh_cmd "[...]"
ssh_cmd "[...]"
ssh_cmd "[...]"

除了您通常使用的内容之外,函数的主体不需要额外的引用,并且 "$@" 确保您对 ssh_cmd 的参数在对 [=13= 的调用中保留为不同的参数].