我正在为Go编写一个CLI向导。我想做的是询问用户他想做什么,准备相应的CLI命令,并将其写入控制台。然后,用户可以通过按Enter键将命令提交给CLI,可能在首先编辑它之后。换句话说,我想将输出写入stdout,当用户按Enter键时,该输出将成为stdin的输入。有没有办法在Go中做到这一点?
答案 0 :(得分:1)
直接从用户那里获取输入:
var s string
_, err := fmt.Scanf("%s", &s)
对于类似curses的应用程序,请看这里: https://github.com/rthornton128/goncurses/blob/master/ncurses.go
它有C绑定。
答案 1 :(得分:0)
我找到了一个Go命令行编辑器程序包https://github.com/peterh/liner,它包含了所请求的功能以及更多功能。它允许您编写具有历史记录和命令完成功能的CLI,命令完成功能提供了我在问题中所要求的内容:它提供了用户可以编辑并提交给CLI的文本。它支持Windows,Linux和Mac。以下是README中示例的略微修改版本,它运行一个带命令完成的简单CLI。例如,用户可以键入“j”并按Tab键循环显示名称列表,编辑一个名称,然后按Enter键提交。
package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/peterh/liner"
)
var (
history_fn = ".liner_history"
names = []string{"jack", "john", "james", "mary", "mike", "nancy"}
)
func main() {
line := liner.NewLiner()
defer line.Close()
line.SetCompleter(func(line string) (c []string) {
for _, n := range names {
if strings.HasPrefix(n, strings.ToLower(line)) {
c = append(c, n)
}
}
return
})
if f, err := os.Open(history_fn); err == nil {
line.ReadHistory(f)
f.Close()
}
line.SetCtrlCAborts(true)
for true {
if name, err := line.Prompt("What is your name? "); err != nil {
if err.Error() == "EOF" || err == liner.ErrPromptAborted {
break
}
log.Print("Error reading line: ", err)
} else {
log.Print("Got: ", name)
line.AppendHistory(name)
}
}
fmt.Printf("End of test\n")
if f, err := os.Create(history_fn); err != nil {
log.Print("Error writing history file: ", err)
} else {
line.WriteHistory(f)
f.Close()
}
}