首頁  >  文章  >  後端開發  >  如何從 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刪除