Search code examples
shellgogcloud

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


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


Solution

  • Found it why your snippet doesn't work as expected.

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

    Here gcloud command didn't finish the execution, so we have to read it realtime. I have tested the below code snippet, it works.

    cmd := exec.Command("bash", "-c", "gcloud auth application-default login")
    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("Standby to read...")
    fmt.Println()
    

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