leemcloughlin / expect Goto Github PK
View Code? Open in Web Editor NEWExpect is pure Go (golang) version of the terminal interaction package Expect common on many Linux systems
Expect is pure Go (golang) version of the terminal interaction package Expect common on many Linux systems
The attached batch_mock.py reads a username from stdin and then prints results to stdout.
Running this in go, I wanted to handle the prompt with an Expect
case, and then simply read whatever was written to the pty
off the Expect
struct.
Multiple attempts failed. At first I was confused and tried to read off the exp.File
, which did not work, since output is all consumed by the expectReader
goroutine.
Then I had timing problems when debugging, in order to properly see the debug
output, I had to add a Sleep
statement at the end:
package main
import (
"fmt"
"log"
"regexp"
"time"
"github.com/leemcloughlin/expect"
)
func main() {
expect.Debug = true
exp, cmd, err := expect.NewExpectProc("batch_mock.py")
if err != nil {
log.Fatalf("NewExpectProc failed %s", err)
}
exp.SetTimeoutSecs(5)
i, _, err := exp.Expect(regexp.MustCompile(`^\s*username: >> $`))
if i == 0 {
exp.Send("This is a username\r")
} else {
log.Fatalf("failed %s", err)
}
if err = cmd.Wait(); err != nil {
fmt.Println("cmd error", err)
}
time.Sleep(5 * time.Second)
}
When I run this, I see the following:
[...]
2016/10/31 20:30:23 expectReader read 1, ", %!s(<nil>)
2016/10/31 20:30:23 expectReader read 1, }, %!s(<nil>)
, %!s(<nil>)0:30:23 expectReader read 1,
2016/10/31 20:30:23 expectReader read 1,
, %!s(<nil>)
2016/10/31 20:30:23 expectReader read 0,
, read /dev/ptmx: input/output error
2016/10/31 20:30:23 expectReader ending read error
expectReader ENDING
This shows that the data is being read, given that the goroutine has enough time to run.
The problem is that the data is only available through another Expect
call, since the copying from the exp.bytesIn
to the exp.Buffer
happens inside the Expect
function, not autonomously.
An elegant approach of doing this autonomously is the idiomatic reader loop in James Harr's expect package: perhaps there is a possibility for reuse?
Thank you for this useful package, I have been looking for something like this for a long time;
having used tcl/expect in the past, the other go-based packages were not what I expected (pun
not intended).
The expect
package provides a Kill
function, which can be used to stop a process after interacting with it through the pty
.
For the use case of a normally terminating process (e.g. running an ssh process with password prompt, which then executes a single remote command), there is no way of querying the exit status.
This information can be very useful to evaluate, in addition to the command-stdout/stderr buffer.
Expose, in some form, the return value (*os.ProcessState, error
) of cmd.Process.Wait
.
I don't understand how to use the Expect.BufStr().
Let's say I have this command that prints this:
Here are your choices:
1) Go to Smith valley
2) Go to Victoria street
3) Go home
Your choice: <-- wait for input here
If I write this in my code:
exp, _ := expect.NewExpect(myCmd)
exp.Expect("Your choice: ")
// exp.BufStr() is already empty at this line because the exp.Expect() matched and reset the buffer
// I can't parse my choices then
How can I read the choices after the exp.Expect()
call?
Could you please add a license (for example, in the LICENSE
) file to the repository - so that it would be clear if you allow others to use your code! ๐ Thanks.
This is an enhancement suggestion, in the interest of a simple and small API.
The API exposes 2 methods that wrap bytes.Buffer
calls:
func (exp *Expect) Clear() {}
func (exp *Expect) BufStr() string {}
These calls are equivalent according to
e.Clear()
== e.Buffer.Reset()
e.BufStr()
== e.Buffer.String()
If acceptable, remove, perhaps a test program calling the buffer methods.
With Golang 1.15, I faced this error when spawning a expect.NewExpect()
:
Setctty set but Ctty not valid in child
The issue has been fixed in this PR: creack/pty#103
I think you should switch the pty
lib from:
"github.com/kr/pty"
to:
"github.com/creack/pty"
I forced the requirement in my go.mod
:
require (
github.com/creack/pty v1.1.11
)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.