Live filtering of SSH session output in Go

Greetings!
I am relatively low-skilled as Go is concerned, so this might come off a newbish a question. In any case…

I have a need to filter the constant stream of output incoming from an SSH session.

The library used is “golang.org/x/crypto/ssh”.

I have relative confusion around bytes.Buffer/io.Reader in trying to implement the ability to filter each newline incoming from the SSH session to match for a specific string, which is my goal.

It seems the current code I have is passed a pointer to a bytes.Buffer object:

	if err := session.RequestPty("vt100", 80, 40, modes); err != nil {
		//if err := session.RequestPty("vt220", 80, 40, modes); err != nil {
		log.Printf("[ERROR] SSH PTY Error for %s (%s)", "target", err.Error())
		return
	}

	if err := session.Shell(); err != nil {
		log.Printf("[ERROR] SSH Shell Setup Error for %s (%s)", "target", err.Error())
		return
	}

	r, err := session.StdoutPipe()
	if err != nil {
		log.Printf("[ERROR] SSH Output Pipe Error for %s (%s)", "target", err.Error())
		return
	}
	var buff bytes.Buffer
	session.Stdout = &buff

In reading on the matter, one of the methods suggested for doing this sort of work is to use something like this:

func main() {
    input := "foo\nbar\nbaz"
    scanner := bufio.NewScanner(strings.NewReader(input))
    // Not actually needed since it’s a default split function.
    scanner.Split(bufio.ScanLines)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}

However, as this method requires an io.Reader object, I am at a loss at to how I can link my bytes.Buffer to this. Again, I am quite the beginner, so the basics truths around Go might yet escape me.

How should I proceed and if it isnt with the above code, I am quite happy to change the approach. I know that there is a StdOutPipe available in the SSH library, but I am not sure that would help either.

The output coming from the SSH session is essentially a debug command on a network device.

Thank you much!
Mat

2 Likes

Hi, @mnantel, I don’t quite understand what you’re trying to do; it sounds like you’re trying to filter out lines that don’t match an expected substring. If that’s the case, can’t you just grep the data?

2 Likes

Hi. bytesbuffer implements the reader interface (see https://golang.org/pkg/bytes/#Buffer.Read) so you can use it directly

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.