如何从 Python 通过 SSH 在控制台菜单 (pdmenu) 上导航?
How to navigate on console menu (pdmenu) over SSH from Python?
我必须测试 SSH
上远程计算机上可用的伪图形菜单 (pdmenu
)。像我这样的最佳菜单示例是 mc
、htop
或 tzconfig
,但它们要复杂得多。
无论如何,我不知道如何阅读此菜单并进行导航。
在我的项目中使用了 paramiko
包装器,但我可以直接切换到 pexpect
或 subprocess
(pexpect
是 subprocess
的包装器)。
我的目标是能够 发送 箭头键 到菜单,查找(或读取文本)突出显示的行, 发送 enter, space, escape, 检测并发送文本到 文本字段s。 可能吗?
我宁愿解决方案是跨平台的。
当然可以。但是,您必须解析 ascii 响应(流)以找到您需要的所有元素(例如突出显示的字符),这些元素可能不是微不足道的并且依赖于终端。
这是 ASCII control chars 的列表。例如,ESC
将是 \x1b
,Space
将是 \x20
,Enter
将是 \r
。
特殊键和颜色表示为ANSI-Escape sequences。例如,right arrow
将是 \x1b[C
,left arrow
将是 \x1b[D
,up arrow
将是 \x1b[A
,而 down arrow
将是 \x1b[B
。 Highlighted
或 inverted
文本将以 \x1b[7m
为前缀,blinking
文本将以 \x1b[5m
为前缀,依此类推。
谈到 paramiko,您很可能必须 ssh.invoke_shell()
并不断从该频道接收信息,同时评估您收到的信息,以便了解远程菜单中实际发生的情况。通过 clear-screen escape sequence
检测一个屏幕的结束应该相当容易
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy( paramiko.AutoAddPolicy() )
ssh.connect(ip, username='root', password="password")
chan = ssh.invoke_shell()
while not chan.exit_status_ready()
buff = ''
while not buff.endswith('\x1b[2J'):
resp = chan.recv(1) # tweak, bigger chunks, use select.
buff += resp
# buff hold data up to clear-screen
# evaluate screen, send keystrokes to navigate
chan.send('\x1b\r') # ESC
这应该可以帮助您入门。
我必须测试 SSH
上远程计算机上可用的伪图形菜单 (pdmenu
)。像我这样的最佳菜单示例是 mc
、htop
或 tzconfig
,但它们要复杂得多。
无论如何,我不知道如何阅读此菜单并进行导航。
在我的项目中使用了 paramiko
包装器,但我可以直接切换到 pexpect
或 subprocess
(pexpect
是 subprocess
的包装器)。
我的目标是能够 发送 箭头键 到菜单,查找(或读取文本)突出显示的行, 发送 enter, space, escape, 检测并发送文本到 文本字段s。 可能吗?
我宁愿解决方案是跨平台的。
当然可以。但是,您必须解析 ascii 响应(流)以找到您需要的所有元素(例如突出显示的字符),这些元素可能不是微不足道的并且依赖于终端。
这是 ASCII control chars 的列表。例如,ESC
将是 \x1b
,Space
将是 \x20
,Enter
将是 \r
。
特殊键和颜色表示为ANSI-Escape sequences。例如,right arrow
将是 \x1b[C
,left arrow
将是 \x1b[D
,up arrow
将是 \x1b[A
,而 down arrow
将是 \x1b[B
。 Highlighted
或 inverted
文本将以 \x1b[7m
为前缀,blinking
文本将以 \x1b[5m
为前缀,依此类推。
谈到 paramiko,您很可能必须 ssh.invoke_shell()
并不断从该频道接收信息,同时评估您收到的信息,以便了解远程菜单中实际发生的情况。通过 clear-screen escape sequence
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy( paramiko.AutoAddPolicy() )
ssh.connect(ip, username='root', password="password")
chan = ssh.invoke_shell()
while not chan.exit_status_ready()
buff = ''
while not buff.endswith('\x1b[2J'):
resp = chan.recv(1) # tweak, bigger chunks, use select.
buff += resp
# buff hold data up to clear-screen
# evaluate screen, send keystrokes to navigate
chan.send('\x1b\r') # ESC
这应该可以帮助您入门。