我正在使用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会话的行为方式相同,或者至少可以理解两者的行为方式不同。
答案 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()