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

问题描述

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

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} "[...]"

只要不将空格用作路径或选项的一部分,这就会起作用,因为根据我的理解,上面使用的前缀会受到外壳程序的分词。当然,出于各种原因,我有一些带有空格的选项,这些选项需要按原样转发,作为一个参数。上面的例子不是这种情况,整个命令都失败了。 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 的参数在对 ssh 的调用中保留为不同的参数。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...