Skip to content

spawn ssh send large/long command got /r(carriage return) and (/b)backspace  #5

Description

@slmint

when spawn ssh client , send large/long command , expect recv /r and /b

we can:

  • use stty -echo disable input echo , just pick up output , but block on some device
  • resize tty size use github.com/kr/pty.Setsize

has better way? etc syscall.SYS_IOCTL+syscall.ECHO?

test code

func TestExpect_SSH(t *testing.T) {
	var PROMPT = `(?m)[^$]*#` // or (?m)[^$]*$
	exp, err := expect.Spawn(
		"ssh",
		"-F", "/dev/null",
		"-o", "UserKnownHostsFile /dev/null",
		"-o", "StricthostKeyChecking false",
		"localhost",
	)
	if err != nil {
		t.Error("Unexpected error spawning 'ssh'", err)
	}

	defer exp.Close()
	exp.SetLogger(expect.TestLogger(t))
	exp.SetTimeout(time.Second * 15)

	// Login
	exp.Expect(`[Pp]assword:`)
	exp.SendMasked("ban password")
	exp.Send("\n")
	exp.Expect(PROMPT) // Wait for prompt

	time.Sleep(1 * time.Second)

	// tty attr
	exp.SendLn("stty -a")
	match, err := exp.Expect(PROMPT) // Wait for prompt
	t.Logf("stty -a:%s", match.Before)

	// less then column size
	exp.SendLn("echo START_1234567890_1234567890_END")
	match, err = exp.Expect(PROMPT) // Wait for prompt
	t.Logf("long command output:%s", match.Before)

	exp.Send("\n")
	exp.Expect(PROMPT) // Wait for prompt

	// got carriage return 
	exp.SendLn("echo START_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_END")
	match, err = exp.Expect(PROMPT) // Wait for prompt
	t.Logf("long command output:%s", match.Before)

	exp.SetWinSize(10240, 768)

	exp.SendLn("echo START_0987654321_0987654321_END")
	match, err = exp.Expect(PROMPT) // Wait for prompt
	t.Logf("long command output:%s", match.Before)

	exp.Send("\n")
	exp.Expect(PROMPT) // Wait for prompt

	exp.SendLn("echo START_0987654321_0987654321_0987654321_0987654321_0987654321_0987654321_0987654321_0987654321_0987654321_0987654321_0987654321_0987654321_END")
	match, err = exp.Expect(PROMPT) // Wait for prompt
	t.Logf("long command output:%s", match.Before)

	time.Sleep(5 * time.Second)

	// Wait for EOF
	exp.SendLn("exit")
	exp.ExpectEOF()
}

func SetWinSize

func (exp *Expect) SetWinSize(rows, cols uint16) error {
	ws := pty.Winsize{rows, cols, 0, 0}
	return pty.Setsize(exp.pty.(*os.File), &ws)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions