如何将整个命令存储在 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= 的调用中保留为不同的参数].
我有很多行如下,其中前缀总是相同的,实际执行的命令不同。
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= 的调用中保留为不同的参数].