在Go語言開發(fā)中,有時候我們可能會遇到從”HijackedResponse”中刪除光標(biāo)位置的ANSI轉(zhuǎn)義代碼的需求。這些轉(zhuǎn)義代碼通常用于在終端上展示彩色文本或者控制光標(biāo)位置,但是在某些情況下,我們可能需要將其刪除。本文將介紹如何通過使用Go語言的字符串操作函數(shù)以及正則表達(dá)式,從”HijackedResponse”中刪除這些ANSI轉(zhuǎn)義代碼。無論您是Go語言初學(xué)者還是有一定經(jīng)驗的開發(fā)者,本文都將幫助您解決這一問題。
問題內(nèi)容
我正在嘗試使用 go 執(zhí)行(交互)一個 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 }
登錄后復(fù)制
…并在此處調(diào)用 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 }
登錄后復(fù)制
一些注意事項:
sh
是必需的,它是高山圖像
injection.container
只是保存有關(guān)容器的信息,它是一個自定義結(jié)構(gòu)體
docker
是一個結(jié)構(gòu)體,用于保存 docker 客戶端(來自 github.com/docker/docker/client 的 client
的實例)
如果我執(zhí)行我的應(yīng)用程序,我得到的 cli 結(jié)果是這樣的:
/usr/app $ ^[[43;12r
據(jù)我所知,^[[43;12r 是光標(biāo)位置的 ansi 轉(zhuǎn)義碼。
我可以執(zhí)行命令,例如 ls
或 npm i
等,但我總是找回這些 ansi 轉(zhuǎn)義碼。
我的問題是,有沒有辦法從標(biāo)準(zhǔn)輸出中刪除它們?
解決方法
我最終發(fā)現(xiàn)了。
問題是,我應(yīng)該使用 github.com/docker/cli/cli/command
包及其 dockercli
而不是 os.std...
。這可以通過設(shè)置輸出、錯誤和輸入流來為我管理這個問題,如下所示:
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 }
登錄后復(fù)制
如果要添加ctrl+c轉(zhuǎn)義,需要在containerexeccreate
處的execconfig
中設(shè)置detachkeys
。否則執(zhí)行 exit
將分離它。