interact

September 24, 2026 · View on GitHub

interact 提供命令行交互式输入辅助能力。

它包含常见终端交互方法,例如:

  • ReadInput
  • ReadLine
  • ReadFirst
  • Prompt
  • Confirm
  • Query/Question/Ask
  • Select/Choice
  • MultiSelect/Checkbox
  • ReadPassword
  • Collectorcparam

文档

安装

go get github.com/gookit/cliui/interact

新 UI 层

interact/ui 是一个新的抽象层,用于构建由 backend 驱动的交互组件。

  • package: github.com/gookit/cliui/interact/ui
  • 当前 backend: github.com/gookit/cliui/interact/backend/plain
  • 事件驱动 backend: github.com/gookit/cliui/interact/backend/readline
  • readline.New() 在非 TTY 输入下会回退到 plain
  • readline.NewStrict() 在无法使用 TTY 时会直接返回错误,而不是回退
  • Input 支持 UTF-8 行编辑和常用快捷键
  • SelectMultiSelect 支持禁用项、默认值、导航键和可见的选择状态
  • 详情:interact-ui.md

interact 包也提供了一组 bridge helper:

  • NewUIInput
  • NewUIConfirm
  • NewUISelect
  • NewUIMultiSelect
  • NewUIPlainBackend
  • NewUIReadlineBackend
  • NewUIStrictReadlineBackend
  • NewUIFakeBackend

如果测试或应用需要替换 interactinteract/uishowprogress 共享的默认输入/输出流,可以使用根包 github.com/gookit/cliui 提供的辅助方法:

cliui.CustomIO(in, out)
defer cliui.ResetIO()

快速示例

Read Input

ReadInput 用于读取一行普通文本输入,适合简单参数、名称、路径等一次性输入。

name, err := interact.ReadInput("Your name: ")
if err != nil {
	panic(err)
}
fmt.Println("name:", name)

效果示例:

Your name: tom
name: tom

Prompt

Prompt 支持上下文控制和默认值,适合需要可取消、可超时或统一管理上下文的输入流程。

answer, err := interact.Prompt(context.Background(), "Environment", "dev")
if err != nil {
	panic(err)
}
fmt.Println("env:", answer)

效果示例:

Environment [dev]: prod
env: prod

Confirm

Confirm 用于确认类问题,返回布尔值,适合删除、覆盖、部署等需要用户确认的操作。

ok, err := interact.Confirm("Continue? ", true)
if err != nil {
	panic(err)
}
if ok {
	fmt.Println("confirmed")
}

效果示例:

Continue? [Y/n] y
confirmed

Question

Question/Ask 用于带默认值和可选校验的问题输入,适合声明式地组织单个问题。

name, err := interact.Ask("Your name?", "guest", nil)
if err != nil {
	panic(err)
}
fmt.Println("name:", name)

需要配置或复用问题时,可以使用 NewQuestion

value, err := interact.NewQuestion("Your name?", "guest").Run()
if err != nil {
	panic(err)
}
fmt.Println(value.String())

效果示例:

Your name? [guest]: tom
tom

Select

Select 用于从多个候选项中选择一个值,适合环境、区域、模板、操作类型等单选场景。

city, err := interact.SelectOne(
	"Your city?",
	[]string{"chengdu", "beijing", "shanghai"},
	"",
)
if err != nil {
	panic(err)
}
fmt.Println("city:", city)

效果示例:

Your city?
  1) chengdu
  2) beijing
  3) shanghai
Please select: 1
city: chengdu

Multi Select

Multi Select 用于选择多个值,适合批量启用模块、选择服务、选择标签等多选场景。

services, err := interact.MultiSelect(
	"Choose services",
	[]string{"api", "worker", "web"},
	[]string{"api"},
)
if err != nil {
	panic(err)
}
fmt.Println("services:", services)

效果示例:

Choose services
  1) api
  2) worker
  3) web
Please select: 1,3
services: [api web]

需要同时获取选中项的 key 和 value 时,可以直接使用 NewSelect

s := interact.NewSelect("Choose env", []string{"dev", "prod"})
result, err := s.Run()
if err != nil {
	panic(err)
}
fmt.Println(result.KeyString(), result.String())

Password

ReadPassword 用于读取敏感输入,终端中不会回显实际内容。

password := interact.ReadPassword("Password: ")
fmt.Println("password length:", len(password))

效果示例:

Password:
password length: 8

Collector

Collector 可以组合多个输入参数并按顺序执行:

c := interact.NewCollector()
err := c.AddParams(
	cparam.NewStringParam("name", "Your name"),
	cparam.NewChoiceParam("env", "Choose env").WithChoices([]string{"dev", "prod"}),
)
if err != nil {
	panic(err)
}

效果示例:

Your name: tom
Choose env
  1) dev
  2) prod
Please select: 2

UI Bridge

如果希望使用新的 interact/ui 组件,但不直接引入子包,可以使用 bridge helper:

be := interact.NewUIReadlineBackend()

name, err := interact.NewUIInput("Your name").Run(context.Background(), be)
if err != nil {
	panic(err)
}

fmt.Println("name:", name)

效果示例:

Your name: tom
name: tom

完整 Select 示例

package main

import (
	"fmt"

	"github.com/gookit/color"
	"github.com/gookit/cliui/interact"
)

func main() {
	color.Green.Println("This's An Select Demo")
	fmt.Println("----------------------------------------------------------")

	ans, err := interact.SelectOne(
		"Your city name(use string slice/array)?",
		[]string{"chengdu", "beijing", "shanghai"},
		"",
	)
	if err != nil {
		panic(err)
	}
	color.Info.Println("your select is:", ans)
	fmt.Println("----------------------------------------------------------")

	ans1, err := interact.Choice(
		"Your age(use int slice/array)?",
		[]int{23, 34, 45},
		"",
	)
	if err != nil {
		panic(err)
	}
	color.Info.Println("your select is:", ans1)

	fmt.Println("----------------------------------------------------------")

	ans2, err := interact.SingleSelect(
		"Your city name(use map)?",
		map[string]string{"a": "chengdu", "b": "beijing", "c": "shanghai"},
		"a",
	)
	if err != nil {
		panic(err)
	}
	color.Info.Println("your select is:", ans2)

	s := interact.NewSelect("Your city", []string{"chengdu", "beijing", "shanghai"})
	s.DefOpt = "2"
	r, err := s.Run()
	if err != nil {
		panic(err)
	}
	color.Info.Println("your select key:", r.K.String())
	color.Info.Println("your select val:", r.String())
}

预览:

select

相关项目