使用Golang在交互式shell中访问Docker容器

huangapple go评论77阅读模式
英文:

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.Stdinnil文档中提到

// 如果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

huangapple
  • 本文由 发表于 2022年7月29日 01:37:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/73157047.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定