Pexpect和终端调整大小

时间:2017-06-05 12:38:11

标签: terminal resize pexpect

我正在使用pexpect自动将ssh-ing引入提示输入密码的远程服务器。这个过程非常简单,效果很好:

child = pexpect.spawn("ssh -Y remote.server")
child.expect(re.compile(b".*password.*"))
child.sendline(password)
child.interact()

这很好用,但是,我注意到一个令人讨厌的怪癖,我一直无法弄明白。当我在这个终端中使用vim时,它似乎没有正确调整大小。当直接sshing,并使用像vim这样的程序时,我可以调整我的终端窗口(本地),远程程序自动/交互式地修复列和行。我的pexpect实例没有。还有一些其他的小问题我可以参与,但这个很烦人。

我希望找到一种方法可以使我的pexpect ssh会话的行为方式与本机ssh会话的行为方式相同,或者至少可以理解两者的行为方式不同。

2 个答案:

答案 0 :(得分:0)

pexpect's doc中的interact()功能实际上就是一个例子。就像编写C代码一样,它需要一个SIGWINCH处理程序。

import pexpect, struct, fcntl, termios, signal, sys

def sigwinch_passthrough (sig, data):
    s = struct.pack("HHHH", 0, 0, 0, 0)
    a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(),
                                          termios.TIOCGWINSZ , s) )
    global p
    p.setwinsize(a[0], a[1])

# Note this 'p' global and used in sigwinch_passthrough.
p = pexpect.spawn('/bin/bash')
signal.signal(signal.SIGWINCH, sigwinch_passthrough)

p.interact()

答案 1 :(得分:0)

SIGWINCH处理窗口大小更改。如果需要它的行为与本机ssh相同,则还应该设置pexpect初始窗口大小:

import pexpect, struct, fcntl, termios, signal, sys

def get_terminal_size():
    s = struct.pack("HHHH", 0, 0, 0, 0)
    a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, s))
    return a[0], a[1]

def sigwinch_passthrough(sig, data):
    global p
    if not p.closed:
        p.setwinsize(*get_terminal_size())

p = pexpect.spawn('/bin/bash')
# Set the window size the same of current terminal window size
p.setwinsize(*get_terminal_size())
# Hook the window change signal so that the pexpect window size change as well
signal.signal(signal.SIGWINCH, sigwinch_passthrough)

p.interact()