无法通过 ssh 隧道在远程主机上执行嵌套命令

无法通过 ssh 隧道在远程主机上执行嵌套命令

我在我的 GitLab CI 作业中运行以下命令:

ssh ${REMOTE_HOST} "docker restart $(docker ps --format '{{.Names}}' | grep '^backend')"

问题是它返回以下错误:

/usr/bin/bash: line 156: docker: command not found
"docker restart" requires at least 1 argument.

我知道它docker确实存在并且可以在远程主机上运行,​​因为我可以登录到主机的 shell 并自己执行 docker 命令。

根据我的理解,错误似乎是双重的 - 它告诉我“未找到docker命令”,然后告诉我“docker restart至少需要1个参数”。

因此,我假设docker嵌套命令未找到可执行文件,该命令返回“docker:未找到命令”错误,并且由于该命令不返回容器名称,因此docker restart也会失败。

我也尝试在嵌套命令中替换docker/usr/bin/docker但无济于事。

我知道 ssh 隧道工作正常,因为就在执行该命令之前,我执行了以下两个命令,它们工作正常:

ssh ${REMOTE_HOST} "docker pull my_registry/backend:${VERSION} "
ssh ${REMOTE_HOST} "docker-compose -f docker-compose.yml up --detach --remove-orphans"

所以,我确实相信问题在于docker没有找到内部命令的可执行文件。

答案1

双引号字符串仍然允许本地 bash shell 扩展字符串内的变量、命令替换等。

这意味着您的命令将docker ps --format '{{.Names}}' | grep '^backend'在本地机器上执行,而不是您所希望的在远程机器上执行。

ssh ${REMOTE_HOST} "docker restart $(docker ps --format '{{.Names}}' | grep '^backend')"

您可以尝试使用以下方法进行转义:

ssh ${REMOTE_HOST} "docker restart \$(docker ps --format '{{.Names}}' | grep '^backend')"

或者使用单引号。以下是示例:

ssh ${REMOTE_HOST} 'docker restart $(docker ps --format {{.Names}} | grep ^backend)'

更多详细信息,您可以找到重击(1)手册页中的 QUOTING 部分。

   There are three quoting mechanisms: the escape character, single
   quotes, and double quotes.

   A non-quoted backslash (\) is the escape character.  It preserves
   the literal value of the next character that follows, with the
   exception of <newline>.  If a \<newline> pair appears, and the
   backslash is not itself quoted, the \<newline> is treated as a
   line continuation (that is, it is removed from the input stream
   and effectively ignored).

   Enclosing characters in single quotes preserves the literal value
   of each character within the quotes.  A single quote may not
   occur between single quotes, even when preceded by a backslash.

   Enclosing characters in double quotes preserves the literal value
   of all characters within the quotes, with the exception of $, `,
   \, and, when history expansion is enabled, !.  When the shell is
   in posix mode, the ! has no special meaning within double quotes,
   even when history expansion is enabled.  The characters $ and `
   retain their special meaning within double quotes.  The backslash
   retains its special meaning only when followed by one of the
   following characters: $, `, ", \, or <newline>.  A double quote
   may be quoted within double quotes by preceding it with a
   backslash.  If enabled, history expansion will be performed
   unless an !  appearing in double quotes is escaped using a
   backslash.  The backslash preceding the !  is not removed.

相关内容