Hi Everyone: I came across a problem which puzzled me for couple of days. I am trying to write a* SSH client with a Interactive Shell *using golang, but i also need to record the command(or keystroke history) of the user typed, like the history feature, here's my working code:
ce := func(err error, msg string) { if err != nil { log.Fatalf("%s error: %v", msg, err) } } var ( auth []ssh.AuthMethod SSH client with a addr string clientConfig *ssh.ClientConfig client *ssh.Client config ssh.Config session *ssh.Session err error key string ) user := "vagrant" addr = "localhost:2222" key = "my_vagrant_private_key_path" auth = make([]ssh.AuthMethod, 0) pemBytes, err := ioutil.ReadFile(key) if err != nil { panic(err) } var signer ssh.Signer signer, err = ssh.ParsePrivateKey(pemBytes) if err != nil { panic("parse error") } auth = append(auth, ssh.PublicKeys(signer)) if err != nil { panic("public key append error") } auth = append(auth, ssh.PublicKeys(signer)) config = ssh.Config{ Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-...@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"}, } clientConfig = &ssh.ClientConfig{ User: user, Auth: auth, Timeout: 30 * time.Second, Config: config, HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil }, } client, err = ssh.Dial("tcp", addr,clientConfig) ce(err, "dial") session, err = client.NewSession() ce(err, "new session") defer session.Close() session.Stdout = os.Stdout session.Stderr = os.Stderr session.Stdin = os.Stdin modes := ssh.TerminalModes{ ssh.ECHO: 1, ssh.ECHOCTL: 0, ssh.TTY_OP_ISPEED: 14400, ssh.TTY_OP_OSPEED: 14400, } termFD := int(os.Stdin.Fd()) w, h, _ := terminal.GetSize(termFD) termState, _ := terminal.MakeRaw(termFD) defer terminal.Restore(termFD, termState) err = session.RequestPty("xterm-256color", h, w, modes) ce(err, "request pty") SSH client with a err = session.Shell() ce(err, "start shell") err = session.Wait() ce(err, "return") So far, it works well as a SSH client which provide an interactive shell, which handle arrow keys, key combination like Ctrl+L(clear screen), Ctrl+r(show command history), ctrl+c correctly. My problem is I cannot find the way to log, or record command history, if I copied os.Stdin, and pass that to Session, it shows like "session's stdin is not a terminal" warning, and the arrow keys, key combanition support is lost, when I press arrow key, it shows something like [[A on the screen. I've searched the internet a lot, and tried to read some pty/tty articles, but not get a clue. Anyone knows how to record command history to it, while make the key handle properly at the moment? (like the real SSH client we use) -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.