如何在Golang中获取gcloud命令的结果?

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

How to get the result of a gcloud command in golang?

问题

这是我的代码:

  1. package main
  2. import (
  3. "os/exec"
  4. "log"
  5. "fmt"
  6. )
  7. func main() {
  8. out, err := exec.Command("bash", "-c", "gcloud auth application-default login").Output()
  9. if err != nil {
  10. log.Fatal(err)
  11. }
  12. fmt.Printf("输出为:%s\n", out)
  13. }

当我执行这段代码时,它会在浏览器中打开正确的URL...
但是我想要获取这个URL。

当我在shell中输入以下命令时:

  1. gcloud auth application-default login

我得到的输出是:

  1. Your browser has been opened to visit:
  2. https://accounts.google.com/o/oauth2/auth?redirect_uri=h***********************************

我希望在我的程序中使用out变量获取这段文本。
有什么办法可以实现吗?

编辑:以下是我尝试过但没有成功的三种方法:

  1. /*
  2. out, err := exec.Command("bash", "-c", "gcloud auth application-default login").CombinedOutput()
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. fmt.Printf("输出为:%s\n", out)
  7. */
  8. cmd := exec.Command("bash", "-c", "gcloud auth application-default login")
  9. cmdReader, err := cmd.StderrPipe()
  10. if err != nil {
  11. fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for Cmd", err)
  12. os.Exit(1)
  13. }
  14. scanner := bufio.NewScanner(cmdReader)
  15. go func() {
  16. for scanner.Scan() {
  17. fmt.Printf("输出 | %s\n", scanner.Text())
  18. }
  19. }()
  20. out, err := exec.Command("bash", "-c", "gcloud auth application-default login").Output()
  21. if err != nil {
  22. log.Fatal(err)
  23. }
  24. fmt.Printf("输出为:%s\n", out)

祝好!谢谢。

英文:

Here is my code :

  1. package main
  2. import (
  3. "os/exec"
  4. "log"
  5. "fmt"
  6. )
  7. func main() {
  8. out, err := exec.Command("bash", "-c", "gcloud auth application-default login").Output()
  9. if err != nil {
  10. log.Fatal(err)
  11. }
  12. fmt.Printf("The output is %s\n", out)
  13. }

When i exec this code it opens me my browser with the good url ...
But i would like to get the url.

When i type this command :

  1. gcloud auth application-default login

in my shell i have :

  1. Your browser has been opened to visit:
  2. https://accounts.google.com/o/oauth2/auth?redirect_uri=h***********************************

And that's the text that i would like to get with the Out in my program.

Any idea how to get it ?

edit here are 3 thigns that i've tested with no sucess

  1. /*
  2. out, err := exec.Command("bash", "-c", "gcloud auth application-default login").CombinedOutput()
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. fmt.Printf("The output is %s\n", out)
  7. */
  8. cmd := exec.Command("bash", "-c", "gcloud auth application-default login")
  9. cmdReader, err := cmd.StderrPipe()
  10. if err != nil {
  11. fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for Cmd", err)
  12. os.Exit(1)
  13. }
  14. scanner := bufio.NewScanner(cmdReader)
  15. go func() {
  16. for scanner.Scan() {
  17. fmt.Printf(" out | %s\n", scanner.Text())
  18. }
  19. }()
  20. out, err := exec.Command("bash", "-c", "gcloud auth application-default login").Output()
  21. if err != nil {
  22. log.Fatal(err)
  23. }
  24. fmt.Printf("The date is %s\n", out)

Regards and Thanks

答案1

得分: 5

发现为什么你的代码片段不能按预期工作。

通常CombinedOutput()Output()会在给定命令完成后返回结果。

在这里,gcloud命令没有执行完毕,所以我们需要实时读取它。我已经测试了下面的代码片段,它可以工作。

  1. cmd := exec.Command("bash", "-c", "gcloud auth application-default login")
  2. stderr, err := cmd.StderrPipe()
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. // 启动命令
  7. if err = cmd.Start(); err != nil {
  8. log.Fatal(err)
  9. }
  10. // 防止 main() 在 cmd 完成之前退出
  11. defer cmd.Wait()
  12. // 读取命令输出并发送到标准输出
  13. // 根据需要替换 os.Stderr
  14. go io.Copy(os.Stdout, stderr)
  15. fmt.Println("Standby to read...")
  16. fmt.Println()
  17. 这只是一种方法你可以根据自己的需求进行实现祝你好运
  18. <details>
  19. <summary>英文:</summary>
  20. Found it why your snippet doesn&#39;t work as expected.
  21. Typically `CombinedOutput()` and `Output()` returns the result after completion of given command.
  22. Here `gcloud` command didn&#39;t finish the execution, so we have to read it realtime. I have tested the below code snippet, it works.
  23. cmd := exec.Command(&quot;bash&quot;, &quot;-c&quot;, &quot;gcloud auth application-default login&quot;)
  24. stderr, err := cmd.StderrPipe()
  25. if err != nil {
  26. log.Fatal(err)
  27. }
  28. // Start command
  29. if err = cmd.Start(); err != nil {
  30. log.Fatal(err)
  31. }
  32. // prevent main() to exit before cmd completes
  33. defer cmd.Wait()
  34. // read cmd output and send it to stdout
  35. // repalce os.Stderr as per your need
  36. go io.Copy(os.Stdout, stderr)
  37. fmt.Println(&quot;Standby to read...&quot;)
  38. fmt.Println()
  39. This is just an approach, implement yours. Good luck!
  40. </details>
  41. # 答案2
  42. **得分**: 0
  43. 该消息被打印到标准错误流(stderr)而不是标准输出流(stdout)
  44. <details>
  45. <summary>英文:</summary>
  46. That message is printed to stderr, not stdout.
  47. </details>

huangapple
  • 本文由 发表于 2017年6月11日 06:22:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/44478623.html
匿名

发表评论

匿名网友

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

确定