What is the best way to save ssh output into a struct in golang?

Issue

I’m trying to save output of running some commands on other machine with SSH, into a struct.
I used CombinedOutput to save the output. Something like this:

...
combo, err := session.CombinedOutput("hostname;pwd")
outputResult = string(combo)
...

It gives me a 2-line output. I want to save these lines into the below struct:

type Result struct {
    Hostname string `json:"hostname"`
    PWD      string `json:"pwd"`
}

What is the best (and easy) way to do that? Thanks.

Solution

It gives me a 2-line output. I want to save these lines into the below struct

Your question really has nothing to do with SSH. You have a []byte that represents the output of your commands. You want to split it into two strings.

strings.SplitN is the perfect solution for this. You pass it the original string (to which the []byte must be converted), the separator (\n in your case), and the maximum number of strings to return. For us, we want at most 2 strings. How could there be more than one \n? pwd returns a directory, and directories can have newlines in their names, though they very rarely do in practice.

    out := []byte("myhost\n/dir")
    fmt.Println(string(out))
    strs := strings.SplitN(string(out), "\n", 2)
    res := Result{Hostname: strs[0], PWD: strs[1]}
    out := []byte("myhost\n/dir")
    fmt.Println(string(out))
    strs := strings.SplitN(string(out), "\n", 2)
    res := Result{Hostname: strs[0], PWD: strs[1]}

https://go.dev/play/p/5ENSgAPg3ER

combo, err := session.CombinedOutput("hostname;pwd")

Remember that this will also include the stderr in addition to the stdout. I can’t think of a situation where either command would generate any output to stderr, but keep in mind that you’re not distinguishing between the two. Hopefully you’re checking the result of err and if not nil, not consuming the results of the command. That should protect you from unanticipated results from the combination of stdout and stderr. If stderr is never relevant for you, you might want to use ssh.Session.Output instead

Answered By – Daniel Farrell

Answer Checked By – Cary Denson (GoLangFix Admin)

Leave a Reply

Your email address will not be published.