预期和终端调整大小
Pexpect and Terminal Resizing
我正在使用 pexpect 自动通过 ssh 连接到提示输入密码的远程服务器。过程非常简单,效果很好:
child = pexpect.spawn("ssh -Y remote.server")
child.expect(re.compile(b".*password.*"))
child.sendline(password)
child.interact()
这很好用,但是,我注意到一个我一直无法弄清楚的非常烦人的怪癖。当我在此终端中使用 vim 时,它似乎无法正确调整大小。当直接 ssh-ing 并使用诸如 vim 之类的程序时,我可以调整终端 window(本地)的大小,而远程程序 automatically/interactively 会修复列和行。我的预期实例没有。还有一些我可以忍受的小怪癖,但是这个很烦人。
我希望找到一种方法,使我的预期 ssh 会话的行为与本机 ssh 会话的行为相同,或者至少理解两者行为不同的原因。
在 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()
SIGWINCH
处理 window 尺寸变化。如果你需要它的行为与原生 ssh 相同,你还应该设置 pexpect initial window size:
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()
我正在使用 pexpect 自动通过 ssh 连接到提示输入密码的远程服务器。过程非常简单,效果很好:
child = pexpect.spawn("ssh -Y remote.server")
child.expect(re.compile(b".*password.*"))
child.sendline(password)
child.interact()
这很好用,但是,我注意到一个我一直无法弄清楚的非常烦人的怪癖。当我在此终端中使用 vim 时,它似乎无法正确调整大小。当直接 ssh-ing 并使用诸如 vim 之类的程序时,我可以调整终端 window(本地)的大小,而远程程序 automatically/interactively 会修复列和行。我的预期实例没有。还有一些我可以忍受的小怪癖,但是这个很烦人。
我希望找到一种方法,使我的预期 ssh 会话的行为与本机 ssh 会话的行为相同,或者至少理解两者行为不同的原因。
在 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()
SIGWINCH
处理 window 尺寸变化。如果你需要它的行为与原生 ssh 相同,你还应该设置 pexpect initial window size:
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()