Home > Mobile >  Access docker container in interactive shell using Golang
Access docker container in interactive shell using Golang

Time:07-30

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

CodePudding user response:

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
  • Related