google / goexpect Goto Github PK
View Code? Open in Web Editor NEWExpect for Go
License: BSD 3-Clause "New" or "Revised" License
Expect for Go
License: BSD 3-Clause "New" or "Revised" License
In ExpectSwitchCase()
we do:
// Clear the buffer directly after match.
o := tbuf.String()
tbuf.Reset()
This means that back to back Expect
will not work if the matching string for the second Expect
call is already in buffer.
For example the following code will fail:
exp.Expect(regexp.MustComplie("StringA"))
exp.Expect(regexp.MustCopmile("StrinbB"))
If our buffer is already "StringA...StringB" by the time we call exp.Expect(regexp.MustComplie("StringA"))
.
Real world use case is doing multiple Expect to much long strings during bootup, will work when run against real situation, but will fail during UT.
Instead of nuking the whole buffer, we should only be deleting up to the point of the last match. That's how the rest of "expect" libraries work if I am not mistaken.
It happened that there is no data in e when timer.C was up, in funtion ExpectSwitchCase.
Spawn fails on Go 1.13:
$ go run ./examples/process/ 10
F0625 11:06:45.549888 104755 process.go:45] fork/exec /usr/bin/bc: operation not permitted
exit status 1
Culprit is https://go-review.googlesource.com/c/go/+/178919 ("syscall: use Ctty before fd shuffle").
If I'm following correctly, the problem is here:
cmd.SysProcAttr = &syscall.SysProcAttr{
Setsid: true,
Setctty: true}
Setting Setctty
sets the controlling terminal to SysProcAttr.Ctty
, which is unset (i.e., 0
), which is probably not the desired behavior.
Hi, the crew, great job of this package!
Line 1161 in b5b7712
As said, goexpect wirte stdout and stderr both to an io.Writer (if any). Isn't it resonable to handle them separately?
BTW, tee
command itself merely captures stdout. ;P
In Pexpect, you can issue a ctrl-c command like expect.sendcontrol('c'). Is there a way to do this with goexpect?
D:\01work\internal_software\trunk\devLicense\wlic\client>go version
go version go1.17 windows/amd64
D:\01work\internal_software\trunk\devLicense\wlic\client>go build
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:202:32: not enough arguments in call to syscall.Syscall
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:202:33: undefined: syscall.SYS_IOCTL
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:213:32: not enough arguments in call to syscall.Syscall
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:213:33: undefined: syscall.SYS_IOCTL
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:288:32: not enough arguments in call to syscall.Syscall
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:288:33: undefined: syscall.SYS_IOCTL
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:310:32: not enough arguments in call to syscall.Syscall
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:310:33: undefined: syscall.SYS_IOCTL
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:319:32: not enough arguments in call to syscall.Syscall
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:319:33: undefined: syscall.SYS_IOCTL
C:\Users\yxhlc\go\pkg\mod\github.com\google\[email protected]\term\termios.go:319:32: too many errors
D:\01work\internal_software\trunk\devLicense\wlic\client>
Right now when using SpawnSSH/SpawnSSHPTY goexpect will create a SSH Session object and call the Shell method automatically. While this works great for lots of network devices, for other devices (ex: servers) it would be great to be able to call the Run method without creating a shell as that adds additional parsing complexity ($PS1, etc) when you only want to run a single command. I think exporting the underlying Session object could work or adding the command to run as an Option which would change logic in SpawnSSHPTY to call session.Run instead of session.Shell would also work.
Hi
We are using goexpect at https://github.com/kubevirt/kubevirt [1]
With the following settings to SpawnGeneric:
opts = append(opts, expect.Verbose(true))
opts = append(opts, expect.VerboseWriter(GinkgoWriter))
On one hand it is perfect for us that only upon error or verbose mode, we see all the logged info.
The problem is that if there is an error, we have a custom error reporter, which also uses SpawnGeneric
in order to trigger some more commands that collect data.
Those commands would print as well all the collected info to the console, which cause it to be too loaded with info
which is not needed (it is saved to files as well where it belongs).
Is there a way to have two SpawnGeneric, where one prints to GinkgoWriter, while the other prints to /dev/null
or doesn't print at all ?
Tried few configurations, but no luck yet (changes might be required in the NewExpecter as well i believe)
For example tried to have a different buffer and control it (I believe I didn't do it right if it suppose to work)
Thanks
Sometimes, when we have network connectivity issues inside of cluster our tests is stuck on
goroutine 20 [chan send, 170 minutes]:
kubevirt.io/kubevirt/vendor/github.com/google/goexpect.(*GExpect).Send(0xc000f96500, 0x15464fb, 0x1, 0xc000d40e68, 0x40d72f)
/root/go/src/kubevirt.io/kubevirt/vendor/github.com/google/goexpect/expect.go:1093 +0x90
kubevirt.io/kubevirt/vendor/github.com/google/goexpect.(*GExpect).ExpectBatch(0xc000f96500, 0xc000cf0360, 0x9, 0x9, 0x29e8d60800, 0xc000d1d900, 0x3e, 0x0, 0x1711660, 0xc000cb65d0)
/root/go/src/kubevirt.io/kubevirt/vendor/github.com/google/goexpect/expect.go:595 +0x7b9
kubevirt.io/kubevirt/tests.LoggedInCirrosExpecter(0xc0010b1800, 0xc000c8aa40, 0xc000704f00, 0x0, 0x0)
/root/go/src/kubevirt.io/kubevirt/tests/utils.go:2069 +0x534
kubevirt.io/kubevirt/tests_test.generateHelloWorldServer(0xc0010b1800, 0x1756360, 0xc000704f00, 0x50, 0x1546d7f, 0x3)
...
our LoggedInCirrosExpecter
uses ExpectBatch
method with 3 minutes timeout, but it stuck forever if it no input from the expecter.
The package http://github.com/golang/glog defines several flags in its init()
.
When a program defines some flags and imports http://github.com/google/goexpect it may have some flags redefined.
Would be great if goexpect
(due to glog
) does not restrict the set of flags that can be used. For this I have two proposals:
glog
completely and use log
package.glog
partially by allowing the user to set their custom logger for the package. Implement glog
and log
interface in this custom logger.The first one is poorly implemented here: http://github.com/tinti/goexpect
Wondering if there's any way to send a file over SSH.
I'm working with automation of configuration using NETCONF, and need to send over a file with the configuration and subsequently respond to prompts.
More specifically, I need to run the following SSH command:
ssh -o StrictHostKeyChecking=no -p $PORT admin@$HOST -s netconf < $CONFIG_FILE
The python pexpect
package allows the spawning of a command to be executed. So I could perform the following:
cmd_to_execute = f'/bin/bash -c "ssh -o StrictHostKeyChecking=no -p {cm_port} admin@{cm_host} -s netconf < {config_file}"'
child = pexpect.spawn(cmd_to_execute)
What would be an equivalent goexpect way of performing such action?
I use exec.Command("ssh", "user@addr")
to create a system process, and use ExpectBatcher
to send password expecting login automatically. However, this wouldn't work since the password promot comming neither from stdout nor stderr.
As said, OpenSSH client directly talks to /dev/tty
which makes goexpect
unable to receive any data from stdout/stderr, resulting in Expect
not working.
This is not covered by current version, and it's pretty interesting to talk about.
Example code
package main
import (
"fmt"
"io"
"os"
"os/exec"
"syscall"
expect "github.com/google/goexpect"
)
func main() {
cmd := exec.Command("ssh", "localhost")
bs := []expect.Batcher{
&expect.BExpT{R: "password: ", T: 2},
&expect.BSnd{S: "some_password\n"},
}
pr1, pw1 := io.Pipe()
pr2, pw2 := io.Pipe()
cmd.Stdin, cmd.Stdout = pr1, pw2
err := cmd.Start()
if err != nil {
closeDescriptors(pr1, pw1, pr2, pw2)
panic(fmt.Sprintf("1: %s", err))
}
opt := &expect.GenOptions{
In: pw1,
Out: pr2,
Wait: func() error { return nil },
Close: func() error { return cmd.Process.Kill() },
Check: func() bool {
if cmd.Process == nil {
return false
}
// Sending Signal 0 to a process returns nil if
// process can take a signal , something else if not.
return cmd.Process.Signal(syscall.Signal(0)) == nil
},
}
exp, _, err := expect.SpawnGeneric(opt, -1, expect.Verbose(true), expect.VerboseWriter(os.Stdout))
if err != nil {
closeDescriptors(pr1, pw1, pr2, pw2)
panic(fmt.Sprintf("2: %s", err))
}
// not working since no data coming out from stdout/stderr
res, err := exp.ExpectBatch(bs, -1)
if err != nil {
panic(fmt.Sprintf("3: %s", err))
}
for _, item := range res {
fmt.Printf(">>> find res: %s\n", item.Output)
}
fmt.Println("done")
}
func closeDescriptors(closers ...io.Closer) {
for _, closer := range closers {
_ = closer.Close()
}
}
For example, the command line touch 'x y'
contains two args, not three: touch
and x y
. goexpect does not support arguments containing spaces when spawning processes.
The proposal is to change the signature of Spawn from:
func Spawn(command string, timeout time.Duration, opts ...Option) (*GExpect, <-chan error, error)
To:
func Spawn(command []string, timeout time.Duration, opts ...Option) (*GExpect, <-chan error, error)
It's almost a year since it was updated
Yesterday I had working code based on the AsyncInteractChannels example.
Today with the same code I am getting the error Setctty set but Ctty not valid in child
It appears I am triggering the issue described here golang/go#29458 but I'm not sure what to check further to confirm.
I've upgraded golang from 1.15.2 to 1.15.5 and still get the error.
Running on MacOS.
In https://github.com/google/goexpect/blob/master/expect.go#L840 and https://github.com/google/goexpect/blob/master/expect.go#L1224 you return a locally defined error. It would be great if you would define that error as an exported variable so that callers could more cleanly check for it.
Hello, thanks for this cool package!
I am using the VerboseWriter
option to redirect verbose logging to my implementation of io.Writer
. However, it looks like there's no way to redirect goexpect's non-verbose logging in the same way, or am I missing something? I would like to be able to redirect both since I'm using custom logging code, currently the non-verbose logging falls out of line.
I am using go 1.14 on windows 10 when trying to build dll file with this command :
go build -buildmode=shared
I get this error message :
-buildmode=shared not supported on windows/amd64
In example code ssh_example
,
e.ExpectBatch([]expect.Batcher{
&expect.BCas{[]expect.Caser{
&expect.Case{R: regexp.MustCompile(`router#`), T: expect.OK()},
&expect.Case{R: regexp.MustCompile(`Login: `), S: *user,
T: expect.Continue(expect.NewStatus(codes.PermissionDenied, "wrong username")), Rt: 3},
&expect.Case{R: regexp.MustCompile(`Password: `), S: *pass1, T: expect.Next(), Rt: 1},
----> here &expect.Case{R: regexp.MustCompile(`Password: `), S: *pass1,
T: expect.Continue(expect.NewStatus(codes.PermissionDenied, "wrong password")), Rt: 1},
}},
}, timeout)
I believe it means to try pass2
instead of trying pass1
again.
SpawnSSH
and SpawnGeneric
both use waitForSession
which appears to use a different code path than SpawnWithArgs
, and the output does not pass through teeWriter
.
The first link referenced in the Basic Examples section is misleading as it does not contain goexpect examples let alone any reference to the goexpect library.
Tests on master branch fails:
goexpect/master$ go test .
2018/09/11 23:43:37 at login prompt
2018/09/11 23:43:37 at password prompt
2018/09/11 23:43:39 Done sent
E0911 23:43:39.901595 19055 expect_test.go:136] Accept failed: accept tcp [::]:65226: use of closed network connection
E0911 23:43:39.910121 19055 expect_test.go:204] PTY cols/rows: 240/22 want: 120/40
E0911 23:43:39.910250 19055 expect_test.go:136] Accept failed: accept tcp [::]:65231: use of closed network connection
2018/09/11 23:43:39 Write failed: io: read/write on closed pipe
2018/09/11 23:43:39 Write failed: io: read/write on closed pipe
--- FAIL: TestSpawn (0.00s)
expect_test.go:948: Nil return code: Spawn("/bin/true") = true want: false, err: inappropriate ioctl for device
expect_test.go:948: Non nil return code: Spawn("/bin/false") = true want: false, err: inappropriate ioctl for device
expect_test.go:948: Spawn cat: Spawn("/bin/cat") = true want: false, err: inappropriate ioctl for device
--- FAIL: TestSpawnWithArgs (0.00s)
expect_test.go:971: Spawn(echo 'a b') failed: inappropriate ioctl for device
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0x11ee48c]
goroutine 46 [running]:
testing.tRunner.func1(0xc000110900)
/usr/local/opt/go/libexec/src/testing/testing.go:792 +0x387
panic(0x123f720, 0x144d5a0)
/usr/local/opt/go/libexec/src/runtime/panic.go:513 +0x1b9
github.com/google/goexpect.(*GExpect).ExpectSwitchCase(0x0, 0xc000251ec8, 0x1, 0x1, 0x17d78400, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/Users/hachi8833/deve/golang/gopath/sys/src/github.com/google/goexpect/expect.go:620 +0x1cc
github.com/google/goexpect.(*GExpect).Expect(0x0, 0xc0004020a0, 0x17d78400, 0xc000251f58, 0x1, 0x1, 0x0, 0x0, 0x0, 0x12c4100)
/Users/hachi8833/deve/golang/gopath/sys/src/github.com/google/goexpect/expect.go:1125 +0xd1
github.com/google/goexpect.TestSpawnWithArgs(0xc000110900)
/Users/hachi8833/deve/golang/gopath/sys/src/github.com/google/goexpect/expect_test.go:975 +0x139
testing.tRunner(0xc000110900, 0x1295258)
/usr/local/opt/go/libexec/src/testing/testing.go:827 +0xbf
created by testing.(*T).Run
/usr/local/opt/go/libexec/src/testing/testing.go:878 +0x353
FAIL github.com/google/goexpect 4.220s
goexpect fails when the client expects payloads larger than the default buffer size.
A dynamically growing byte slice will not work in this instance, due to the fact that the PTY File is not closed after receiving command output (i.e., does not receive io.EOF). As such, something like ioutil.ReadAll(...)
cannot be used in this context, and will eventually just timeout waiting for io.EOF or an error.
Support should be added to at least make bufferSize
configurable, preferably per GExpect
instance.
The readme isn't useful unless you already know what expect is. If you don't, then it is meaningless (and it's hard to google "expect").
Say, I run cat /proc/kmsg
as a root user on the interfactive SSH shell spawned by SpawnWithArgs
, but it will hangs for ever (since you wouldn't cat anything from the magic file /proc/kmsg
even as root), so no following commands sent to this SSH shell will not be executed by the SSH shell since it is haning on. I'd like invoke Ctrl-C
in this SSH shell spawned by goexpect
to stop cat
progress clearing the shell, just like what we will do in an actual one.
I've tried
\003
(by calling exp.Write()
) wouldn't work.SendSignal
batcher seems send signals to the SSH progress itself, not she SHELL
inside the SSH session.Are there any ways to do this? What did I miss here?
I am having a problem when using goroutines. If i make connections one by one - the connections are successful, I get the data.
But if I run many goroutines at the same time, then they freeze and die by timeout. And I tracked down - freezes occur after sending the password. What am I doing wrong?
import (
"fmt"
"log"
"regexp"
"sync"
"time"
expect "github.com/google/goexpect"
)
const (
timeout = 30 * time.Second
)
var (
userRE = regexp.MustCompile("UserName:")
passRE = regexp.MustCompile("PassWord:")
promptRE = regexp.MustCompile("admin#")
list []string = []string{"dlink1.domain.com",
"dlink2.domain.com",
"dlink3.domain.com",
"dlink4.domain.com"
}
)
func main() {
log.Println("Telnet example start")
// Running multiple goroutines
var wg sync.WaitGroup
wg.Add(len(list))
for _, router := range list {
// the problem occurs here
/* go */ CallToRouter("username", "pass", router, "1a:1a:1a:1a:1a:1a", searcher, &wg)
}
wg.Wait()
log.Println("Done!")
}
func CallToRouter(user, pass, router, macForSearch string, regexp *regexp.Regexp, wg *sync.WaitGroup) {
defer wg.Done()
// Connect to router
e, _, err := expect.Spawn(fmt.Sprintf("telnet %s", router), -1)
if err != nil {
log.Panic(err)
return
}
defer e.Close()
// Authorizer, exec command, exit
_, _, err = e.Expect(userRE, timeout)
if err != nil {
log.Panic(err)
return
}
err = e.Send(user + "\n")
if err != nil {
log.Panic(err)
return
}
_, _, err = e.Expect(passRE, timeout)
if err != nil {
log.Panic(err)
return
}
err = e.Send(pass + "\n")
if err != nil {
log.Panic(err)
return
}
_, _, err := e.Expect(promptRE, timeout)
if err != nil {
log.Panic(err)
return
}
err = e.Send("sh fdb mac " + macForSearch + "\n")
if err != nil {
log.Panic(err)
return
}
result, _, _ := e.Expect(promptRE, timeout)
if err != nil {
log.Panic(err)
return
}
err = e.Send("logout\n")
if err != nil {
log.Panic(err)
return
}
log.Printf("%s:\n%s", router, result)
}
I've had a good experience using this package to ssh into servers. However, I have not been able to get it to work on a Cisco device via ssh yet. The native go ssh package works, but not this one. Since I need to do a few complex tasks, I'd rather use this package if possible.
The first time that I execute e.Expect(promptRE, timeout), it shows the login banner. However, when I send another command and call e.Expect again, the output received is the command I sent. I tried the exact verbose setup from the verbose example and this was the output...
Match for RE: "Password:" found: ["Password:"] Buffer: Cisco UCS Fabric Interconnect
Password:
Sent: "password\n"
Match for RE: "#" found: ["#"] Buffer:
Cisco Nexus Operating System (NX-OS) Software
TAC support: http://www.cisco.com/tac
Copyright (c) 2009, Cisco Systems, Inc. All rights reserved.
The copyrights to certain works contained in this software are
owned by other third parties and used and distributed under
license. Certain components of this software are licensed under
the GNU General Public License (GPL) version 2.0 or the GNU
Lesser General Public License (LGPL) Version 2.1. A copy of each
such license is available at
http://www.opensource.org/licenses/gpl-2.0.php and
http://www.opensource.org/licenses/lgpl-2.1.php
DEV-1-A#
Sent: "show version\n"
Match for RE: "DEV-1-A#" found: ["DEV-1-A#"] Buffer: show version
DEV-1-A#
cmd: show version: result: show version
The code producing this was...
e.Send("show version\n")
time.Sleep(time.Second)
result, _, _ = e.Expect(promptRE, timeout)
fmt.Println("cmd: %s: result: %s\n", cmd, result)
Please let me know if you have any thoughts on how to fix this. I have already tried playing around with the terminal width and had no luck.
C:\Users\u1\go>go version
go version go1.10.3 windows/amd64
C:\Users\u1\go>go get -v github.com/google/goexpect
github.com/google/goterm/term
# github.com/google/goterm/term
src\github.com\google\goterm\term\termios.go:202:32: not enough arguments in call to syscall.Syscall
src\github.com\google\goterm\term\termios.go:202:33: undefined: syscall.SYS_IOCTL
src\github.com\google\goterm\term\termios.go:213:32: not enough arguments in call to syscall.Syscall
src\github.com\google\goterm\term\termios.go:213:33: undefined: syscall.SYS_IOCTL
src\github.com\google\goterm\term\termios.go:288:32: not enough arguments in call to syscall.Syscall
src\github.com\google\goterm\term\termios.go:288:33: undefined: syscall.SYS_IOCTL
src\github.com\google\goterm\term\termios.go:310:32: not enough arguments in call to syscall.Syscall
src\github.com\google\goterm\term\termios.go:310:33: undefined: syscall.SYS_IOCTL
src\github.com\google\goterm\term\termios.go:319:32: not enough arguments in call to syscall.Syscall
src\github.com\google\goterm\term\termios.go:319:33: undefined: syscall.SYS_IOCTL
src\github.com\google\goterm\term\termios.go:319:32: too many errors
Had a report today from someone wanting some more flexibility with the logging, GLog does not float their boat.
Hi,
How to gives control of the child process to the interactive user (the human at the keyboard) like the interact() method in pexpect?
Lines 1262 to 1264 in c416f18
The switch case
block does not require break
. If break
for loop
, you need a label.
I am attempting to write expect around some queries of Tivoli Storage Manager (IBM Spectrum Protect) and have found that if my queries return only a few lines of output everything works but if my queries return many lines of output I hit the expect timeout.
I modified my program to do a simpler SSH command where executing hostname
is successful but an operation that lists the contents of a directory with a few lines of output times out.
package main
import (
"log"
"os"
"regexp"
"time"
expect "github.com/google/goexpect"
)
var (
passRE = regexp.MustCompile("password:")
promptRE = regexp.MustCompile(`\[tdockendorf@repo ~\]`)
)
func main() {
cmd := "ssh repo"
timeout := time.Duration(5) * time.Second
e, _, err := expect.Spawn(cmd, timeout, expect.Verbose(true), expect.VerboseWriter(os.Stdout))
if err != nil {
log.Fatal(err)
}
defer e.Close()
content, matches, err := e.Expect(passRE, timeout)
if err != nil {
log.Fatalf("error getting password prompt: %v", err)
}
log.Printf("content1: %s matches1: %v", content, matches)
err = e.Send(os.Getenv("PASSWORD") + "\n")
if err != nil {
log.Fatalf("error sending password: %v", err)
}
content, matches, err = e.Expect(promptRE, timeout)
if err != nil {
log.Fatalf("error getting prompt: %v", err)
}
log.Printf("content2: %s matches2: %v", content, matches)
err = e.Send("hostname\n")
if err != nil {
log.Fatalf("error sending command1: %v", err)
}
content, matches, err = e.Expect(promptRE, timeout)
if err != nil {
log.Fatalf("error getting prompt: %v", err)
}
log.Printf("content3: %s matches3: %v", content, matches)
err = e.Send("ls -la /var/www/repos/public/ondemand/\n")
if err != nil {
log.Fatalf("error sending command2: %v", err)
}
content, matches, err = e.Expect(regexp.MustCompile("Protect:"), timeout)
if err != nil {
log.Fatalf("error getting prompt2: %v", err)
}
log.Printf("content4: %s matches4: %v", content, matches)
e.Send("exit\n")
}
OUTPUT:
$ ./test
Match for RE: "password:" found: ["password:"] Buffer: tdockendorf@repo's password:
2020/11/11 10:26:14 content1: tdockendorf@repo's password: matches1: [password:]
Sent: "OMIT-PASSWORD\n"
Match for RE: "\\[tdockendorf@repo ~\\]" found: ["[tdockendorf@repo ~]"] Buffer:
Last login: Wed Nov 11 10:24:09 2020 from pitzer-rw01.ten.osc.edu
******************************************************************************
This system is for the use of authorized users only. Individuals using
this computer system without authority, or in excess of their authority,
are subject to having all of their activities on this system monitored
and recorded by system personnel. In the course of monitoring individuals
improperly using this system, or in the course of system maintenance,
the activities of authorized users may also be monitored. Anyone using
this system expressly consents to such monitoring and is advised that if
such monitoring reveals possible evidence of criminal activity, system
personnel may provide the evidence of such monitoring to law enforcement
officials.
******************************************************************************
[tdockendorf@repo ~]$
2020/11/11 10:26:14 content2:
Last login: Wed Nov 11 10:24:09 2020 from pitzer-rw01.ten.osc.edu
******************************************************************************
This system is for the use of authorized users only. Individuals using
this computer system without authority, or in excess of their authority,
are subject to having all of their activities on this system monitored
and recorded by system personnel. In the course of monitoring individuals
improperly using this system, or in the course of system maintenance,
the activities of authorized users may also be monitored. Anyone using
this system expressly consents to such monitoring and is advised that if
such monitoring reveals possible evidence of criminal activity, system
personnel may provide the evidence of such monitoring to law enforcement
officials.
******************************************************************************
[tdockendorf@repo ~]$ matches2: [[tdockendorf@repo ~]]
Sent: "hostname\n"
Match for RE: "\\[tdockendorf@repo ~\\]" found: ["[tdockendorf@repo ~]"] Buffer: repo.OMIT
[tdockendorf@repo ~]$
2020/11/11 10:26:14 content3: repo.OMIT
[tdockendorf@repo ~]$ matches3: [[tdockendorf@repo ~]]
Sent: "ls -la /var/www/repos/public/ondemand/\n"
2020/11/11 10:26:19 error getting prompt2: expect: timer expired after 5 seconds
Commands executed outside the program:
$ ssh repo
tdockendorf@repo's password:
Last login: Wed Nov 11 10:26:14 2020 from pitzer-rw01.ten.osc.edu
******************************************************************************
This system is for the use of authorized users only. Individuals using
this computer system without authority, or in excess of their authority,
are subject to having all of their activities on this system monitored
and recorded by system personnel. In the course of monitoring individuals
improperly using this system, or in the course of system maintenance,
the activities of authorized users may also be monitored. Anyone using
this system expressly consents to such monitoring and is advised that if
such monitoring reveals possible evidence of criminal activity, system
personnel may provide the evidence of such monitoring to law enforcement
officials.
******************************************************************************
[tdockendorf@repo ~]$ hostname
repo.hpc.osc.edu
[tdockendorf@repo ~]$ time ls -la /var/www/repos/public/ondemand/
total 80
drwxrwxr-x 13 tdockendorf oodpkg 4096 Aug 19 09:04 .
drwxrwxr-x 23 tdockendorf 103 8192 Apr 5 2019 ..
drwxr-xr-x 4 oodpkg oodpkg 4096 May 2 2018 1.3
drwxr-xr-x 4 oodpkg oodpkg 4096 Jan 7 2019 1.4
drwxr-xr-x 4 oodpkg oodpkg 4096 Feb 4 2019 1.5
drwxr-xr-x 4 oodpkg oodpkg 4096 Sep 30 2019 1.6
drwxr-xr-x 4 oodpkg oodpkg 4096 Aug 19 13:32 1.7
drwxr-xr-x 4 oodpkg oodpkg 4096 Aug 19 09:04 1.8
drwxrwxr-x 2 oodpkg oodpkg 16384 Apr 8 2020 archive
drwxrwxr-x 6 oodpkg oodpkg 4096 Nov 6 11:28 build
drwxr-xr-x 4 oodpkg oodpkg 4096 Jul 3 2019 ci
drwxr-xr-x 2 oodpkg oodpkg 4096 Nov 5 14:11 images
drwxr-xr-x 4 oodpkg oodpkg 12288 Aug 19 13:34 latest
-rw-r--r-- 1 root root 1739 Feb 13 2018 RPM-GPG-KEY-ondemand
real 0m0.008s
user 0m0.000s
sys 0m0.004s
Line 621 in 028ffe4
Hello,
After running expect a couple of thousand times it seems there's a memory leak that occurs. I think I've traced it down to the referenced lines and reading through the NewTicker comments they recommend:
// The duration d must be greater than zero; if not, NewTicker will panic.
// Stop the ticker to release associated resources.
I couldn't find the code to stop the Ticker within expect.go. Is there a reason there's no Stop()?
defer chTicker.Stop()
Heap pprof profile without Stop
68.93MB of 68.93MB total ( 100%)
Dropped 52 nodes (cum <= 0.34MB)
flat flat% sum% cum cum%
46MB 66.74% 66.74% 46MB 66.74% runtime.makechan
11.50MB 16.68% 83.42% 45.85MB 66.51% time.NewTicker
4MB 5.80% 89.22% 18.50MB 26.84% time.NewTimer
2.85MB 4.13% 93.35% 2.85MB 4.13% runtime.addtimerLocked
0.88MB 1.28% 94.63% 0.88MB 1.28% compress/flate.NewWriter
0.64MB 0.92% 95.55% 0.64MB 0.92% github.com/golang/glog.(*syncBuffer).rotateFile
Heap pprof profile with Stop
18236.91kB of 18236.91kB total ( 100%)
Dropped 64 nodes (cum <= 91.18kB)
flat flat% sum% cum cum%
9728.73kB 53.35% 53.35% 9728.73kB 53.35% runtime.makechan
5632.34kB 30.88% 84.23% 15361.08kB 84.23% time.NewTimer
1121.44kB 6.15% 90.38% 1121.44kB 6.15% runtime.addtimerLocked
650.62kB 3.57% 93.95% 650.62kB 3.57% github.com/golang/glog.(*syncBuffer).rotateFile
591.75kB 3.24% 97.19% 591.75kB 3.24% crypto/elliptic.initTable
512.02kB 2.81% 100% 512.02kB 2.81% vendor/golang_org/x/net/http2/hpack.addDecoderNode
Example code:
https://github.com/marek5050/GoPprof/blob/master/src/github.com/marek5050/GoProfiling/cmd/lser/main.go
When sending a command, how do I get stdout or stderr?
For example, I would like to see the raw output of the process in a log file. The word "Tee" comes from the GNU tee command.
Hi,
I'm fairly new to go and I'm having a hard time following the source. How can I determine if the regex match of the "Expect" function succeeded?
Thanks,
-G
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.