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 小时前
Stagehand v3多语言SDK:Python/Go/Rust/Java下的浏览器自动化统一方案
python·golang·rust
卷无止境10 小时前
Windows 上丝滑开发 Python,并稳定构建 Docker 镜像
后端·python·docker
吕海洋14 小时前
目前可用的docker源2026.08
运维·docker·容器
gsls20080817 小时前
Penpot Docker 部署与 MCP 服务配置文档
运维·docker·容器·原型·penpot
xrlfreedom18 小时前
大厂 MCP 面试实录:本地 Server 远程化改造中的技术选型与落地实践
docker·json schema·mcp
福大大架构师每日一题19 小时前
ragflow v0.27.0 发布:Go 后端全面对齐、智能体搜索与知识编译大升级,超全更新解析
开发语言·后端·golang
JavaPub-rodert19 小时前
Go 后台如何同时兼容 MySQL、PostgreSQL、SQLite 和 SQL Server?从 ShiyuAdmin 看 GORM 多数据库适配
数据库·mysql·postgresql·golang·javapub·王仕宇
艾伦_耶格宇21 小时前
【DOCKER容器实战】-2MySQL
运维·docker·容器
禅口魔心1 天前
RK3576开发——Docker部署
docker·嵌入式linux
随便做点啥1 天前
32卡×4090 24GB,Qwen3.8-27B-FP8 集群部署报告
服务器·经验分享·docker·vllm