[英]How to execute multiple commands in a Pod's container with client-go?
So I've tried to execute a chain ie multiple commands on a Pod's container using client-go
, and it seems to only work for some commands like ls
.所以我尝试使用client-go
在 Pod 的容器上执行一个链,即多个命令,它似乎只适用于某些命令,如ls
。
Here is what I've tried:这是我尝试过的:
req := client.CoreV1().RESTClient().Post().Resource("pods").Name(pod.Name).Namespace(pod.ObjectMeta.Namespace).SubResource("exec") // .Param("container", containerName)
scheme := runtime.NewScheme()
if err := _v1.AddToScheme(scheme); err != nil {
panic(err.Error())
}
parameterCodec := runtime.NewParameterCodec(scheme)
req.VersionedParams(&_v1.PodExecOptions{
Stdin: false,
Stdout: true,
Stderr: true,
TTY: false,
Container: containerName,
Command: strings.Fields("/bin/sh -c " + command),
}, parameterCodec)
exec, err := remotecommand.NewSPDYExecutor(restConfig, "POST", req.URL())
if err != nil {
panic(err.Error())
}
var stdout, stderr bytes.Buffer
err = exec.Stream(remotecommand.StreamOptions{
Stdin: nil,
Stdout: &stdout,
Stderr: &stderr,
Tty: false,
})
if err != nil {
panic(err.Error())
}
log.Printf("Output from pod: %v", stdout.String())
log.Printf("Error from pod: %v", stderr.String())
When the command
variable is just a simple ls -l
, I get the desired output.当command
变量只是一个简单的ls -l
,我会得到所需的输出。 But when I try to do something like 'ls -l && echo hello'
it produces an error command terminated with exit code 2
.但是,当我尝试执行诸如'ls -l && echo hello'
它会生成一个command terminated with exit code 2
的错误command terminated with exit code 2
。 It doesn't output anything if I only put echo hello
.如果我只输入echo hello
它不会输出任何内容。 However, it does produce the desired output hello
if I remove the Bourne Shell
prefix /bin/sh -c
and the Command
attribute equals to string.Fields("echo hello")
, but this approach doesn't let me chain commands.但是,如果我删除Bourne Shell
前缀/bin/sh -c
并且Command
属性等于string.Fields("echo hello")
,它确实会产生所需的输出hello
,但这种方法不允许我链接命令。
All in all, what I am trying to do is to execute a chain of commands on a Pod's container.总而言之,我想要做的是在 Pod 的容器上执行一系列命令。
The corev1.PodExecOptions.Command
accept value of []string
type. corev1.PodExecOptions.Command
接受[]string
类型的值。
req.VersionedParams(&_v1.PodExecOptions{
Stdin: false,
Stdout: true,
Stderr: true,
TTY: false,
Container: containerName,
Command: cmds,
}, parameterCodec)
where, cmds
can be:其中, cmds
可以是:
cmds := []string{
"sh",
"-c",
"echo $HOME; ls -l && echo hello",
}
Output:输出:
/root
total 68
drwxr-xr-x 2 root root 4096 Feb 24 00:00 bin
drwxr-xr-x 2 root root 4096 Feb 1 17:09 boot
drwxr-xr-x 2 root root 4096 Feb 24 00:00 mnt
drwxr-xr-x 2 root root 4096 Feb 24 00:00 opt
dr-xr-xr-x 396 root root 0 Mar 19 11:47 proc
drwx------ 2 root root 4096 Feb 24 00:00 root
.
.
hello
Explanation: Tim's answer说明:蒂姆的回答
command: ["/bin/sh","-c"]
args: ["command one; command two && command three"]
The command ["/bin/sh", "-c"]
says "run a shell, and execute the following instructions" .命令["/bin/sh", "-c"]
表示“运行 shell,并执行以下指令” 。 The args are then passed as commands to the shell.然后将 args 作为命令传递给 shell。 In shell scripting a semicolon
separates commands, and &&
conditionally runs the following command if the first succeed.在 shell 脚本中, semicolon
分隔命令,如果第一个成功, &&
有条件地运行以下命令。 In the above example, it always runs command one
followed by command two
, and only runs command three
if command two
succeeded.在上面的例子中,它总是运行命令one
然后是命令two
,如果命令two
成功,它只运行命令three
。
NB: For bash, it will be similar to something like below:注意:对于 bash,它将类似于以下内容:
cmds := []string{
"bash",
"-c",
`export MYSQL_PWD=${MYSQL_ROOT_PASSWORD}
mysql -h localhost -nsLNE -e "select 1;" 2>/dev/null | grep -v "*"`,
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.