Example of using expect with a function instead of exec
petems opened this issue · 3 comments
Hi, awesome project!
I'm looking to run go-expect against a function, instead of an os.Exec() object.
Most of the examples I've found for go-expect online are either testing or using os.Exec()
For example, I have the following code:
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func feeder(stdin io.Reader) (string) {
scanner := bufio.NewScanner(stdin)
var text string
fmt.Print("Enter some text: ")
scanner.Scan()
text = scanner.Text()
return text
}
func main() {
text := feeder(os.Stdin)
fmt.Print(text + "\n")
}
So all the function does is take input from stdin and echo it back to you.
So, how do I run that with go-expect?
I'm a newb to Golang so if this is weird forgive me, I'm feeling in the dark using other examples I can find.
I've got this far:
package main
import (
"bufio"
"fmt"
"io"
"bytes"
"time"
expect "github.com/Netflix/go-expect"
)
func feeder(stdin io.Reader) (string) {
scanner := bufio.NewScanner(stdin)
var text string
fmt.Print("Enter some text: ")
scanner.Scan()
text = scanner.Text()
return text
}
func main() {
buf := new(bytes.Buffer)
c, _ := expect.NewConsole(expect.WithStdout(buf))
defer c.Close()
donec := make(chan struct{})
go func() {
defer close(donec)
time.Sleep(time.Second)
c.Send("Hello world")
time.Sleep(time.Second)
c.ExpectEOF()
}()
echoText := feeder(c.Tty())
<-donec
fmt.Print("Reponse", echoText)
}
But this just waits forever and doesn't give "Hello World" to the stdin.
If you can help me get this working, I'd be happy to make a docs PR to add to the readme with a function example 😄
hi @petems , thanks for your interest in this project!
Your example does in fact receive the response correctly, but you're waiting for donec
to close after c.ExpectEOF()
unblocks. Since your function doesn't write to the expect console, and also doesn't produce a EOF, the goroutine will block indefinitely.
I've modified your example a bit:
package main
import (
"bufio"
"fmt"
"io"
expect "github.com/Netflix/go-expect"
)
func feeder(stdin io.Reader) string {
scanner := bufio.NewScanner(stdin)
var text string
fmt.Print("Enter some text: ")
scanner.Scan()
text = scanner.Text()
return text
}
func main() {
c, _ := expect.NewConsole()
defer c.Close()
donec := make(chan struct{})
go func() {
defer close(donec)
c.SendLine("Hello world")
}()
echoText := feeder(c.Tty())
<-donec
fmt.Printf("\nResponse: %s", echoText)
}
This is the output:
~
❯ go run petems.go
Enter some text:
Response: Hello world
The reason why you don't see Hello world
next to Enter some text
is because on terminals the tty is in a mode to echo stdin back so you can see what you type. Since yours is a golang function, you'll have to print out scanned input back to the expect console in order to achieve the same effect.
Awesome, thanks so much that works perfectly! 😄