当 kubectl 在 ssh 上运行时,如何传递命令之类的参数?如果我在没有 ssh 的情况下运行,则将 ls 的 -l 参数传递给 pod shell。我试图逃避,加上引号等,但没有任何效果。
ssh [email protected] kubectl exec -it mypod -n mynamespace -- sh -c ls -l
当 kubectl 在 ssh 上运行时,如何传递命令之类的参数?如果我在没有 ssh 的情况下运行,则将 ls 的 -l 参数传递给 pod shell。我试图逃避,加上引号等,但没有任何效果。
ssh [email protected] kubectl exec -it mypod -n mynamespace -- sh -c ls -l
有用的资源:
ssh
解析远程命令行参数如果您知道要在远程 shell 中执行的确切命令,那么您可以为本地 shell 制作一个命令。我认为远程shell的命令不应该是:
因为它会运行
kubectl
那会运行sh -c ls -l
。在本地尝试后面的代码,你会发现它没有运行ls -l
。这是因为-l
不属于sh
被告知运行的代码。的代码sh
应该是 ; 之后的单个选项参数-c
。进一步的论点(如果有的话)是不同的(比较这个问题)。这意味着最终你需要一个在 shell 中看起来像这样的命令:
sh -c 'ls -l'
.kubectl exec
如果ls -l
是它的单个参数,您将运行它。所以你需要在远程shell中:(让我们选择后一个。)现在您知道要在远程 shell 中执行的确切命令。
ssh
将其作为单个参数传递给您的本地:外部(单)引号将被本地 shell 删除,但多亏了它们
ssh
,大代码字符串 (kubectl … "ls -l"
) 作为单个参数。该代码将包含内部(双)引号。这些将被远程 shell(由 SSH 服务器生成)删除,但由于它们,它们kubectl
将获得小代码字符串 (ls -l
) 作为单个参数;因此,它将生成sh
将代码作为单个参数。在这种情况下,哪个引用使用单引号无关紧要,哪个使用双引号。重要的是引号对是不同的(与例如
a "b "c""
引号不是内部和外部的情况相反,它们是两个单独的对,c
没有被引用)。请注意,不同的工具会消化他们的论点并为下一步构建不同的“代码”:
ssh
可以连接多个参数来为远程 shell 构建代码(这就是你的尝试有点奏效的原因);然后远程外壳解释单个字符串。当我需要保护本地 shell 中的东西(例如引号)时(这里就是这种情况),我更喜欢在本地引用整个代码并将其ssh
作为单个参数传递给它;但这是我的选择。所以
ssh
从一个或多个参数构建一个字符串。kubectl exec
将参数 after--
视为一个数组。在我们的例子中,它sh
使用参数-c
and运行ls -l
(在您的尝试中,参数是-c
,ls
and-l
)。所以
kubectl exec
不建立任何字符串。它从参数数组构建一个要执行的数组。sh -c
仅将一个参数解释-c
为 shell 代码。它不会像ssh
can 那样连接多个参数。想象
sh -c
成一个在本地 shell 中运行代码的接口;并ssh …@…
作为在远程 shell 中运行代码的接口。它们是相似的,每个都生成一个 shell,它将解释作为单个字符串编写的代码。然而它们是不同的,不同之处在于字符串的创建方式:sh -c
从一个参数中获取代码,ssh
从可能的多个参数中构建代码。kubectl exec
是在容器中运行可执行文件的接口。它与其他两个接口的最大区别在于它直接将其参数用作数组。你真的需要
sh -c
吗?我认为在这种情况下足够的。请注意,如果您
"ls -l"
在此处使用(仍在单引号代码中),那么kubectl exec
将尝试运行名为ls -l
(而不是ls
作为-l
参数)的可执行文件。在这里,您不想将内部引号应用于ls -l
.OTOH任何这些:
将起作用,因为
ssh
将为远程 shell 构建相同的字符串(尽管来自不同数量的不同参数)。最后一个例子特别奇怪。它在本地将多个“最终”参数集中到一个中,似乎破坏了逻辑(我的意思是ls
与 更多的关系而-l
不是与-n
,对吧?)。尽管如此,它仍然有效,原因是ssh
从许多中构建一个字符串的方式。sh -c
如果ls -l
您没有真正需要外壳的任何东西(例如,带有 的管道|
,带有重定向的命令,例如的>file
外壳语法if
),则必须这样做。您的命令(或我的固定命令)由几个嵌套工具组成。在每一步中,一个(外部)工具以某种方式消化其参数,并以某种方式在同一主机或另一台主机上生成另一个(内部)工具。最后的结论是你需要知道你正在使用的所有工具,它们解析参数和调用下一个工具的方式。请注意,在我们的示例中,之前有一个本地 shell,
ssh
并且在服务器上的 SSH 守护程序和kubectl
;之间有一个远程 shell。您还需要考虑每个隐式外壳。