Maison > développement back-end > Golang > Comment supprimer le code d'échappement ANSI de la position du curseur de « HijackedResponse » dans Go ?

Comment supprimer le code d'échappement ANSI de la position du curseur de « HijackedResponse » dans Go ?

PHPz
Libérer: 2024-02-09 09:42:19
avant
678 Les gens l'ont consulté

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

Dans le développement du langage Go, nous pouvons parfois rencontrer la nécessité de supprimer le code d'échappement ANSI de la position du curseur de "HijackedResponse". Ces codes d'échappement sont généralement utilisés pour afficher du texte en couleur sur le terminal ou contrôler la position du curseur, mais dans certains cas, nous devrons peut-être les supprimer. Cet article explique comment supprimer ces codes d'échappement ANSI de « HijackedResponse » en utilisant les fonctions de manipulation de chaînes et les expressions régulières du langage Go. Que vous soyez débutant en langage Go ou développeur expérimenté, cet article vous aidera à résoudre ce problème.

Contenu de la question

J'essaie d'exécuter (de manière interactive) un conteneur Docker en utilisant go. Voici le code que j'utilise :

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
}
Copier après la connexion

...et appelez holdhijackedconnection ici :

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
}

Copier après la connexion

Quelques remarques :

  • sh est obligatoire, c'est une image de montagne
  • injection.container Enregistre simplement les informations sur le conteneur, c'est une structure personnalisée
  • docker 是一个结构体,用于保存 docker 客户端(来自 github.com/docker/docker/client 的 clientexemple)

Si j'exécute mon application, le résultat cli que j'obtiens est le suivant :

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

Pour autant que je sache, ^[[43;12r est le code d'échappement ansi pour la position du curseur. Je peux exécuter des commandes comme lsnpm i etc. mais je récupère toujours ces codes d'échappement ansi.

Ma question est la suivante : existe-t-il un moyen de les supprimer de la sortie standard ?

La solution

Je l'ai enfin trouvée.

La question est : dois-je utiliser github.com/docker/cli/cli/command 包及其 dockercli 而不是 os.std.... Cela gère cela pour moi en configurant les flux de sortie, d'erreur et d'entrée comme ceci :

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
}
Copier après la connexion

Si vous souhaitez ajouter ctrl+c escape, vous devez le séparer en containerexeccreate处的execconfig中设置detachkeys。否则执行 exit.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal