英文:
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())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论