dongzhuo5425 2015-03-07 23:41
浏览 125
已采纳

如何使用Go通过SSH发送终端转义序列?

I'm writing a Go program that will connect to a host via SSH using the native x/crypto/ssh library and drop an interative shell.

I'm using RequestPty(), but the (bash) shell on the remote end does not behave as expected with control codes.

When I enter various control characters, they're echoed back by my terminal:

$ ^[[A

The characters still work in the sense that if I press enter after pressing the up arrow, the previous command is run - but the control character output clobbers what should be displayed there. The same goes for tab.

Is there some straightforward way to get this to work? When I've implemented similar systems in the past it hasn't been an issue because I've just shelled out to openssh, and the semantics of process groups sort it all out.

I've studied "The TTY Demystified" and as great as it is it's not clear where to begin.

A couple of things I've thought to investigate:

openssh itself must be doing this work correctly, but it's a real best of a code base to study.

It's not actually clear to me whether this printing is being done by my local terminal emulator or shell or by the code on the remote host.

Where do I begin?


Here is a sample of my code:

conf := ssh.ClientConfig{
    User: myuser,
    Auth: []ssh.AuthMethod{ssh.Password(my_password)}
}
conn, err := ssh.Dial("tcp", myhost, conf)
if err != nil {
    return err
}
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
    return err
}
defer session.Close()
session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Stdin = os.Stdin

modes := ssh.TerminalModes{
    ssh.ECHO: 0
    ssh.TTY_OP_ISPEED: 14400,
    ssh.TTY_OP_OSPEED: 14400
}
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
    return err
}
if err = session.Shell(); err != nil {
    return err
}

return session.Wait()

I've tried this with term values other than xterm: screen-256color and vt100.

For the record - in the real code, instead of just a call to session.Wait(), I have a for/select loop that catches various signals to the process and sends them on to the Session.

  • 写回答

2条回答 默认 最新

  • dongxiong4571 2015-04-29 03:32
    关注

    Disable ECHOCTL terminal mode.

    modes := ssh.TerminalModes{
        ssh.ECHO: 0,
        ssh.ECHOCTL: 0,
        ssh.TTY_OP_ISPEED: 14400,
        ssh.TTY_OP_OSPEED: 14400
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条