golang exec command: stream output to stdout *and* capture output in variable

huangapple go评论128阅读模式
英文:

golang exec command: stream output to stdout *and* capture output in variable

问题

我正在使用Go构建一个CLI,并遇到以下情况。我正在从Go中调用一个bash命令,该命令提示用户进行登录,然后在登录后打印一个令牌。例如:

cmd := exec.Command("vault", "login", "-method=okta", "-format=json", "username=abc")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
_ = cmd.Run()

这样可以很好地流式传输输出,但我无法从用户登录后的命令输出中解析令牌。我尝试过将cmd.Run()包装到像这样这样这样的管道函数中,但在这些情况下返回的输出为空。有什么想法吗?

谢谢!

英文:

I'm building a cli in go and have the following situation. I'm calling a bash command from go that prompts the user for a login, then prints a token after login. For example:

cmd := exec.Command("vault", "login", "-method=okta", "-format=json", "username=abc")
cmd.Stdin = os.Stdinout
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
_ = cmd.Run()

This streams the output nicely, but I have no way to parse the token from the command's output after the user logs in. I've tried to wrap the cmd.Run() into piping functions like this this and this but in both cases the output returned is empty. Any ideas?

Thanks!

答案1

得分: 5

以下是翻译好的内容:

可能有很多包可以完成这个任务,但是自己编写也不难:

package main

import (
	"fmt"
	"os"
	"os/exec"
)

type saveOutput struct {
	savedOutput []byte
}

func (so *saveOutput) Write(p []byte) (n int, err error) {
	so.savedOutput = append(so.savedOutput, p...)
	return os.Stdout.Write(p)
}

func main() {
	var so saveOutput
	cmd := exec.Command("factor", "999999")
	cmd.Stdin = os.Stdin
	cmd.Stdout = &so
	cmd.Stderr = os.Stderr
	_ = cmd.Run()
	fmt.Printf("我得到了这个输出:%s\n", so.savedOutput)
}

Playground: https://go.dev/play/p/T-o3QvGOm5q

英文:

There are probably lots of packages to do this, but it's not hard to whip up your own:

package main

import (
	"fmt"
	"os"
	"os/exec"
)

type saveOutput struct {
	savedOutput []byte
}

func (so *saveOutput) Write(p []byte) (n int, err error) {
	so.savedOutput = append(so.savedOutput, p...)
	return os.Stdout.Write(p)
}

func main() {
	var so saveOutput
	cmd := exec.Command("factor", "999999")
	cmd.Stdin = os.Stdin
	cmd.Stdout = &so
	cmd.Stderr = os.Stderr
	_ = cmd.Run()
	fmt.Printf("I got this output: %s\n", so.savedOutput)
}

Playground: https://go.dev/play/p/T-o3QvGOm5q

答案2

得分: 1

不要白费力气去构建你的结构。
使用bytes.Buffer

package main

import (
    "bytes"
    "log"
)

func main() {
    var buffer bytes.Buffer
    cmd := exec.Command("vault", "login", "-method=okta", "-format=json", "username=abc")
    cmd.Stdout = &buffer
    _ = cmd.Run()
    log.Printf("Vault登录输出:%s", buffer.String())
}
英文:

Don't make your structure for nothing.
Use bytes.Buffer

package main

import (
    "bytes"
    "log"
)

func main() {
    var buffer bytes.Buffer
    cmd := exec.Command("vault", "login", "-method=okta", "-format=json", "username=abc")
    cmd.Stdout = &buffer
    _ = cmd.Run()
    log.Printf("Vault login output: %s", buffer.String())
}

huangapple
  • 本文由 发表于 2022年6月30日 07:22:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/72808811.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定