go - 如何在 golang 中执行交互式 CLI 命令?

标签 go command-line-interface

我正在尝试执行一个要求多个输入的命令,例如,如果您尝试将文件从本地设备复制到远程设备,我们使用 scp test.txt user@domain:~/ 然后它要求我们输入密码。我想要的是我想编写一个 go 代码,我在代码本身中提供密码,例如 pass:='Secret Password'。同样,我有 CLI 命令,它向我们询问 IP、名称等几项内容,因此我需要编写一段代码,我只在代码本身中声明所有值,当我运行代码时它不会询问任何内容只需从代码中获取所有输入并运行 CLI 命令,以防将文件复制到远程它不应该在我运行我的 go 二进制文件时询问我密码它应该直接将我的文件复制到远程决定。

func main() {
    cmd := exec.Command("scp", "text.txt", "user@domain:~/")        
    stdin, err := cmd.StdinPipe()
    if err = cmd.Start(); err != nil {
        log.Fatalf("failed to start command: %s", err)
    }
    io.WriteString(stdin, "password\n")
    if err = cmd.Wait(); err != nil {
    log.Fatalf("command failed: %s", err)
    }
}

如果我使用此代码,它会卡在 user@domain 的密码上:

并且没有文件被复制到远程设备。

最佳答案

解决方案一

你可以用 printf 命令绕过这个

cmd := "printf 'John Doe\nNew York\n35' | myInteractiveCmd"
out, err := exec.Command("bash", "-c", cmd).Output()

方案二

您可以使用 io.Pipe()Pipe 创建同步内存管道,您可以将答案写入 io.Writer,您的 cmd 将从 io.Reader 读取。

r, w := io.Pipe()
cmd := exec.Command("myInteractiveCmd")
cmd.Stdin = r
go func() {
    fmt.Fprintf(w, "John Doe\n")
    fmt.Fprintf(w, "New York\n")
    fmt.Fprintf(w, "35\n")
    w.Close()
}()
cmd.Start()
cmd.Wait()

测试信息 为了测试这一点,我编写了 cmd,它询问姓名、城市、年龄并将结果写入文件。

reader := bufio.NewReader(os.Stdin)

fmt.Print("Name: ")
name, _ := reader.ReadString('\n')
name = strings.Trim(name, "\n")
...

关于go - 如何在 golang 中执行交互式 CLI 命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54418628/

相关文章:

php - 将环境变量传递给 php 命令行脚本

go - 无法安装fabric-sdk-go及其依赖项

go - 如何安全地将我的数据库结果缓存在内存缓存中

Go no install location for directory outside GOPATH 运行时出错 "go get"

node.js - 如何将 STDIN 传递给 node.js 子进程

zend-framework - Zend Framework (PHPUnit) 测试无法运行 (phpunit : command not found/Class 'PHPUnit_Framework_TestCase' not found)

http - 无法成功实现 http.Handler

string - 查找字符串中子字符串的索引,指定起始索引

python - 是否有单行方式在 Python venv 中运行命令?

webpack - 运行 "webpack"而不是 "node_modules/.bin/webpack"