Seems natural to have an architecture where one loop reads the input and
passes complete lines to a consumer. This reading loop would store lines in
a list (array, buffer,...) and thus be able to resubmit them to the
consumer.

On Mon, Oct 22, 2018 at 1:57 PM Sun Frank <elitegobli...@gmail.com> wrote:

> 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.
>
-- 

*Michael T. jonesmichael.jo...@gmail.com <michael.jo...@gmail.com>*

-- 
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.

Reply via email to