Using golang connects to docker container with functional tty

Launch a simple Docker container in standalone (background) mode

docker run -d --name test ubuntu tail -f /dev/null

Here is my simple golang code where I connect to a running container. In the current connection, I want to get functional tty.

package main

import (
  "fmt"
  "os/exec"
  "bufio"
  "io"
  "os"
  "github.com/kr/pty"
)

func main() {
  cmd := exec.Command("docker", "exec", "-it", "test", "bin/bash")

  tty, err := pty.Start(cmd)
  if err != nil {
    fmt.Println("Error start cmd", err)
  }
  defer tty.Close()

  go func() {
    scanner := bufio.NewScanner(tty)
    for scanner.Scan() {
       fmt.Println(scanner.Text())
    }
  }()
  go func() {
    io.Copy(tty, os.Stdin)
  }()

  err = cmd.Wait()
  if err != nil {
    fmt.Println("Error Waiting", err)
  }
}

The less this works, but there are a couple of ideas that do not work, since I will run the docker command from my terminal.

  • After logging in, I do not see the invitation, for example root@ba351b44ca80:/#, only after it returns, it appears, but my currsor is on a new line, where there is no invitation;
  • Also, the arrow does not work until the previous command is received. Only prints.

    root@ba351b44ca80:/#
    ^[[A^[[A^[[A
    

but the previous command is selected behind the scene, and by clicking on return, it is executed.

  1. After executing a command, a prompt is not displayed for the cursor, for example

    root@ba351b44ca80:/# ls
    bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
    boot  etc  lib   media  opt  root  sbin  sys  usr
    <Here my cursor>
    
+4

Source: https://habr.com/ru/post/1653711/


All Articles