英文:
Access docker container in interactive shell using Golang
问题
我正在尝试使用Golang访问正在运行的Docker容器的交互式shell。以下是我尝试过的代码:
package main
import (
"fmt"
"log"
"os"
"os/exec"
)
func main() {
prg := "docker"
arg1 := "exec"
arg2 := "-ti"
arg3 := "df43f9a0d5c4"
arg4 := "bash"
cmd := exec.Command(prg, arg1, arg2, arg3, arg4)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
fmt.Printf("[Command] %s\n", cmd.String())
log.Printf("Running command and waiting for it to finish...")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Command finished with error %s\n", cmd.String())
}
以下是带有错误输出的结果:
> [Command] /usr/bin/docker exec -ti df43f9a0d5c4 bash
> 2022/07/28 19:21:02 Running command and waiting for it to finish...
> the input device is not a TTY
> 2022/07/28 19:21:02 exit status 1 exit status 1
注意:直接在shell上执行此命令时,运行中的Docker容器的交互式shell正常工作。
英文:
I am trying to access interactive shell of a running docker container using Golang.
Here is what I tried.
package main
import (
"fmt"
"log"
"os"
"os/exec"
)
func main() {
prg := "docker"
arg1 := "exec"
arg2 := "-ti"
arg3 := "df43f9a0d5c4"
arg4 := "bash"
cmd := exec.Command(prg, arg1, arg2, arg3, arg4)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
fmt.Printf("[Command] %s\n", cmd.String())
log.Printf("Running command and waiting for it to finish...")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Command finished with error %s\n", cmd.String())
}
AND here is output with error:
> [Command] /usr/bin/docker exec -ti df43f9a0d5c4 bash 2022/07/28
> 19:21:02 Running command and waiting for it to finish... the input
> device is not a TTY 2022/07/28 19:21:02 exit status 1 exit status 1
> Note: Interactive shell of running docker container works fine when executing this command directly on the shell
答案1
得分: 1
你正在传递-t
参数,告诉docker exec
为容器内的执行会话分配一个伪终端。
但是你没有设置cmd.Stdin
,所以cmd.Stdin
是nil
。文档中提到:
// 如果Stdin为nil,则进程从空设备(os.DevNull)读取。
输入不是终端,所以你会得到:
输入设备不是TTY
你说:
注意:在shell中直接执行此命令时,正在运行的docker容器的交互式shell可以正常工作
因为当你直接在shell中运行时,标准输入是终端。
尝试这样做:
cmd.Stdin = os.Stdin
英文:
You are passing -t
, telling docker exec
to allocate a pseudoterminal for the exec session within the container.
But you're not setting cmd.Stdin
to anything, so the cmd.Stdin
is nil
. The documentation says
> // If Stdin is nil, the process reads from the null device (os.DevNull).
The input isn't a terminal so that's why you get
>the input device is not a TTY
You say
> Note: Interactive shell of running docker container works fine when executing this command directly on the shell
Because when you run it directly in the shell, the standard input is a terminal.
Try this:
cmd.Stdin = os.Stdin
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论