How to remove cursor position ANSI escape code from 'HijackedResponse' in Go?

PHPz
Release: 2024-02-09 09:42:19
forward
669 people have browsed it

如何从 Go 中的“HijackedResponse”中删除光标位置 ANSI 转义代码?

In Go language development, sometimes we may encounter the need to delete the ANSI escape code at the cursor position from "HijackedResponse". These escape codes are usually used to display colored text on the terminal or control the cursor position, but in some cases we may need to remove them. This article will introduce how to remove these ANSI escape codes from "HijackedResponse" by using the Go language's string manipulation functions and regular expressions. Whether you are a beginner of Go language or an experienced developer, this article will help you solve this problem.

Question content

I am trying to use go to execute (interactively) a docker container. This is the code I'm using:

func (docker *docker) redirectresponsetooutputstream(outputstream, errorstream io.writer, resp io.reader) error {
    _, err := stdcopy.stdcopy(outputstream, errorstream, resp)
    return err
}

func (docker *docker) holdhijackedconnection(inputstream io.reader, outputstream, errorstream io.writer, resp types.hijackedresponse) error {
    receivestdout := make(chan error)
    if outputstream != nil || errorstream != nil {
        go func() {
            receivestdout <- docker.redirectresponsetooutputstream(outputstream, errorstream, resp.reader)
        }()
    }

    stdindone := make(chan struct{})
    go func() {
        if inputstream != nil {
            io.copy(resp.conn, inputstream)
        }
        resp.closewrite()
        close(stdindone)
    }()

    select {
    case err := <-receivestdout:
        return err
    case <-stdindone:
        if outputstream != nil || errorstream != nil {
            return <-receivestdout
        }
    }

    return nil
}
Copy after login

...and call holdhijackedconnection here:

func (docker *Docker) ContainerExec(ctx context.Context, container *injection.Container) error {
    createResponse, err := docker.client.ContainerExecCreate(ctx, container.ID, types.ExecConfig{
        AttachStdout: true,
        AttachStderr: true,
        AttachStdin:  true,
        Detach:       true,
        Tty:          true,
        Cmd:          []string{"sh"},
    })
    if err != nil {
        return err
    }

    stream, err := docker.client.ContainerExecAttach(ctx, createResponse.ID, types.ExecStartCheck{})
    if err != nil {
        return err
    }

    defer stream.Close()
    docker.holdHijackedConnection(os.Stdin, os.Stdout, os.Stderr, stream)
    return nil
}

Copy after login

Some notes:

  • sh is required, it is a mountain image
  • injection.container Just saves information about the container, it is a custom structure
  • docker is a structure used to save the docker client (an instance of client from github.com/docker/docker/client)

If I execute my application, the cli result I get is this:

/usr/app $ ^[[43;12r

As far as I know, ^[[43;12r is the ansi escape code for the cursor position. I can execute commands like ls or npm i etc. but I always get back these ansi escape codes.

My question is, is there a way to remove them from the standard output?

Solution

I finally found it.

The problem is that I should use the github.com/docker/cli/cli/command package and its dockercli instead of os.std... . This manages this issue for me by setting up the output, error and input streams like this:

func (docker *Docker) holdHijackedConnection(resp types.HijackedResponse) error {
    cli, _ := command.NewDockerCli()
    outputStream := cli.Out()
    errorStream := cli.Err()
    inputStream := cli.In()

    inputStream.SetRawTerminal()
    defer inputStream.RestoreTerminal()

    receiveStdout := make(chan error)
    if outputStream != nil || errorStream != nil {
        go func() {
            receiveStdout <- docker.redirectResponseToOutputStream(outputStream, errorStream, resp.Reader)
        }()
    }

    stdinDone := make(chan struct{})
    go func() {
        if inputStream != nil {
            io.Copy(resp.Conn, inputStream)
        }
        resp.CloseWrite()
        close(stdinDone)
    }()

    select {
    case err := <-receiveStdout:
        return err
    case <-stdinDone:
        if outputStream != nil || errorStream != nil {
            return <-receiveStdout
        }
    }

    return nil
}
Copy after login

If you want to add ctrl c escape, you need to set detachkeys in execconfig at containerexeccreate. Otherwise executing exit will detach it.

The above is the detailed content of How to remove cursor position ANSI escape code from 'HijackedResponse' in Go?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template