golang读取键盘功能按键输入

golang读取键盘功能按键输入

需求

最近业务上需要做一个终端工具,能够直接连到docker容器中进行交互。

技术选型

docker官方提供了python sdk、go sdk和remote api。

https://docs.docker.com/engine/api/sdk/

因为我们需要提供命令行工具,因此采用golang进行开发。

遇到的问题

通过sdk可以正常和容器连接,但是在使用方向键、退格等功能按键时总是出现乱码,导致不能正常使用,

通过万能的google终于解决了golang读取输入键盘按键不能正常使用的问题,特此记录。

解决方案

go 复制代码
ctx := context.Background()
	// 自定义http docker client,可以使用官方推荐初始化方式
	// cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	client, err := cmdutil.NewDockerTcpClient(task.ExecNode, GetApiPort())
	waiter, err := client.ContainerAttach(ctx, task.Info.ID, types.ContainerAttachOptions{
		Stderr: true,
		Stdout: true,
		Stdin:  true,
		Stream: true,
	})
	go io.Copy(os.Stdout, waiter.Reader)
	go io.Copy(os.Stderr, waiter.Reader)

	// "golang.org/x/crypto/ssh/terminal"
	//此处是关键,需要将标准输入转成标准终端输入
	fd := os.Stdin.Fd()
	if terminal.IsTerminal(int(fd)) {
		oldState, err := terminal.MakeRaw(int(fd))
		if err != nil {
			zap.S().Fatalln(err)
		}
		defer terminal.Restore(int(fd), oldState)
	}

	go io.Copy(waiter.Conn, os.Stdin)
	if err != nil {
		panic(err)
	}
	
	//此处将阻塞直到容器被释放
	statusCh, errCh := client.ContainerWait(ctx, task.Info.ID, container.WaitConditionNotRunning)
	select {
	case err := <-errCh:
		if err != nil {
			panic(err)
		}
	case <-statusCh:
	}
	return err

参考:

https://github.com/fsouza/go-dockerclient/issues/707

https://stackoverflow.com/questions/58732588/accept-user-input-os-stdin-to-container-using-golang-docker-sdk-interactive-co

相关推荐
念何架构之路9 小时前
Go reflect 包:结构体反射 —Field、Tag 与 VisibleFields
java·数据库·golang
Java开发追求者9 小时前
windows快速安装docker
windows·docker·安装·1024程序员节
喵了几个咪11 小时前
GoWind Admin 拆解:一个 Sender 接口接 39 个通知渠道
微服务·golang·go·1024程序员节·admin·gowind
骑着蜗牛撵大象32711 小时前
飞牛fnOS部署Damselfly:Compose编排、照片目录与7100固定访问
java·docker·rpc·dubbo·fnos·照片管理·damselfly
一掬净土12 小时前
kubelet 报错如下:docker does not support reopening container log files
docker·云原生·kubelet·logfiles
紧跟先前的步伐13 小时前
Go AI Agent 实战 13|大模型流式输出 Streaming 的实现
人工智能·ai·golang·1024程序员节
TTATTC14 小时前
为什么 Python 做 Agent 总在并发中崩溃?拆解 Blockcell 在 Rust 下的 Host-Cell 隔离与自愈状态机
docker·开源
喵了几个咪14 小时前
GoWind Ops 深度拆解:纯出站 Agent + MQTT 信令,把「管机器、跑项目、发脚本、构建分发」做扎实
golang·gowind
紧跟先前的步伐16 小时前
Go AI Agent 实战 14|多轮对话与上下文历史管理
人工智能·ai·golang·1024程序员节