首页  >  文章  >  后端开发  >  如何从 Go 中的“HijackedResponse”中删除光标位置 ANSI 转义代码?

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

PHPz
PHPz转载
2024-02-09 09:42:19632浏览

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

在Go语言开发中,有时候我们可能会遇到从"HijackedResponse"中删除光标位置的ANSI转义代码的需求。这些转义代码通常用于在终端上展示彩色文本或者控制光标位置,但是在某些情况下,我们可能需要将其删除。本文将介绍如何通过使用Go语言的字符串操作函数以及正则表达式,从"HijackedResponse"中删除这些ANSI转义代码。无论您是Go语言初学者还是有一定经验的开发者,本文都将帮助您解决这一问题。

问题内容

我正在尝试使用 go 执行(交互)一个 docker 容器。 这是我正在使用的代码:

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
}

...并在此处调用 holdhijackedconnection

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
}

一些注意事项:

  • sh 是必需的,它是高山图像
  • injection.container 只是保存有关容器的信息,它是一个自定义结构体
  • docker 是一个结构体,用于保存 docker 客户端(来自 github.com/docker/docker/client 的 client 的实例)

如果我执行我的应用程序,我得到的 cli 结果是这样的:

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

据我所知,^[[43;12r 是光标位置的 ansi 转义码。 我可以执行命令,例如 lsnpm i 等,但我总是找回这些 ansi 转义码。

我的问题是,有没有办法从标准输出中删除它们?

解决方法

我最终发现了。

问题是,我应该使用 github.com/docker/cli/cli/command 包及其 dockercli 而不是 os.std...。这可以通过设置输出、错误和输入流来为我管理这个问题,如下所示:

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
}

如果要添加ctrl+c转义,需要在containerexeccreate处的execconfig中设置detachkeys。否则执行 exit 将分离它。

以上是如何从 Go 中的“HijackedResponse”中删除光标位置 ANSI 转义代码?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除