Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk mengalih keluar kod pelarian ANSI kedudukan kursor daripada "HijackedResponse" dalam Go?

Bagaimana untuk mengalih keluar kod pelarian ANSI kedudukan kursor daripada "HijackedResponse" dalam Go?

PHPz
PHPzke hadapan
2024-02-09 09:42:19632semak imbas

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

Dalam pembangunan bahasa Go, kadangkala kita mungkin menghadapi keperluan untuk mengalih keluar kod melarikan diri ANSI kedudukan kursor daripada "HijackedResponse". Kod melarikan diri ini biasanya digunakan untuk memaparkan teks berwarna pada terminal atau mengawal kedudukan kursor, tetapi dalam beberapa kes kita mungkin perlu mengalih keluarnya. Artikel ini akan memperkenalkan cara untuk mengalih keluar kod melarikan diri ANSI ini daripada "HijackedResponse" dengan menggunakan fungsi manipulasi rentetan bahasa Go dan ungkapan biasa. Sama ada anda seorang pemula bahasa Go atau pembangun yang berpengalaman, artikel ini akan membantu anda menyelesaikan masalah ini.

Kandungan soalan

Saya cuba melaksanakan (secara interaktif) bekas docker menggunakan go. Ini adalah kod yang saya gunakan:

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
}

...dan hubungi holdhijackedconnection di sini:

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
}

Beberapa nota:

  • sh diperlukan, ia adalah imej gunung
  • injection.container Hanya menyimpan maklumat tentang bekas, ia adalah struktur tersuai
  • docker 是一个结构体,用于保存 docker 客户端(来自 github.com/docker/docker/client 的 client contoh)

Jika saya melaksanakan permohonan saya, keputusan cli yang saya dapat ialah ini:

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

Setahu saya, ^[[43;12r ialah kod pelarian ansi untuk kedudukan kursor. Saya boleh melaksanakan arahan seperti lsnpm i dsb. tetapi saya sentiasa mendapatkan kembali kod pelarian ansi ini.

Soalan saya ialah, adakah terdapat cara untuk mengeluarkannya daripada output standard?

Penyelesaian

Saya akhirnya jumpa.

Persoalannya, perlukah saya menggunakan github.com/docker/cli/cli/command 包及其 dockercli 而不是 os.std.... Ini menguruskan ini untuk saya dengan menyediakan aliran output, ralat dan input seperti ini:

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
}

Jika anda ingin menambah ctrl+c escape, anda perlu mengasingkannya dalam containerexeccreate处的execconfig中设置detachkeys。否则执行 exit.

Atas ialah kandungan terperinci Bagaimana untuk mengalih keluar kod pelarian ANSI kedudukan kursor daripada "HijackedResponse" dalam Go?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam