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

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

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

问题

这是我的代码:

package main

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

func main() {
	out, err := exec.Command("bash", "-c", "gcloud auth application-default login").Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("输出为:%s\n", out)
}

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

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

gcloud auth application-default login

我得到的输出是:

Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?redirect_uri=h***********************************

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

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

/*
out, err := exec.Command("bash", "-c", "gcloud auth application-default login").CombinedOutput()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("输出为:%s\n", out)

*/

cmd := exec.Command("bash", "-c", "gcloud auth application-default login")
cmdReader, err := cmd.StderrPipe()
if err != nil {
    fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for Cmd", err)
    os.Exit(1)
}

scanner := bufio.NewScanner(cmdReader)
go func() {
    for scanner.Scan() {
        fmt.Printf("输出 | %s\n", scanner.Text())
    }
}()

out, err := exec.Command("bash", "-c", "gcloud auth application-default login").Output()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("输出为:%s\n", out)

祝好!谢谢。

英文:

Here is my code :

package main

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

func main() {
	out, err := exec.Command("bash", "-c", "gcloud auth application-default login").Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("The output is %s\n", out)
}

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 :

gcloud auth application-default login

in my shell i have :

Your browser has been opened to visit:

    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

/*
out, err := exec.Command("bash", "-c", "gcloud auth application-default login").CombinedOutput()
if err != nil {
	log.Fatal(err)
}
fmt.Printf("The output is %s\n", out)

*/

cmd := exec.Command("bash", "-c", "gcloud auth application-default login")
cmdReader, err := cmd.StderrPipe()
if err != nil {
	fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for Cmd", err)
	os.Exit(1)
}

scanner := bufio.NewScanner(cmdReader)
        go func() {
	for scanner.Scan() {
		fmt.Printf(" out | %s\n", scanner.Text())
	}

}()



out, err := exec.Command("bash", "-c", "gcloud auth application-default login").Output()
if err != nil {
	log.Fatal(err)
}
fmt.Printf("The date is %s\n", out)

Regards and Thanks

答案1

得分: 5

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

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

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

cmd := exec.Command("bash", "-c", "gcloud auth application-default login")
stderr, err := cmd.StderrPipe()
if err != nil {
    log.Fatal(err)
}

// 启动命令
if err = cmd.Start(); err != nil {
    log.Fatal(err)
}

// 防止 main() 在 cmd 完成之前退出
defer cmd.Wait()

// 读取命令输出并发送到标准输出
// 根据需要替换 os.Stderr
go io.Copy(os.Stdout, stderr)

fmt.Println("Standby to read...")
fmt.Println()

这只是一种方法你可以根据自己的需求进行实现祝你好运

<details>
<summary>英文:</summary>

Found it why your snippet doesn&#39;t work as expected.

Typically `CombinedOutput()` and `Output()` returns the result after completion of given command.

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.

    cmd := exec.Command(&quot;bash&quot;, &quot;-c&quot;, &quot;gcloud auth application-default login&quot;)
	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Fatal(err)
	}

	// Start command
	if err = cmd.Start(); err != nil {
		log.Fatal(err)
	}

	// prevent main() to exit before cmd completes
	defer cmd.Wait()

	// read cmd output and send it to stdout
	// repalce os.Stderr as per your need
	go io.Copy(os.Stdout, stderr)

	fmt.Println(&quot;Standby to read...&quot;)
	fmt.Println()

This is just an approach, implement yours. Good luck!


</details>



# 答案2
**得分**: 0

该消息被打印到标准错误流(stderr)而不是标准输出流(stdout)

<details>
<summary>英文:</summary>

That message is printed to stderr, not stdout.

</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:

确定