问题描述
我对Paramiko完全陌生。 我正在处理一个Paramiko脚本,该脚本在命令执行完成后会切换到手动输入。 为了使自动完成工作正常进行,我导入了hint_toolkit,如果远程计算机是Linux,它将运行命令“ compgen -ca”将所有可用命令放入一个变量中。 我想知道在Paramiko SSH会话上按下“ TAB”键时如何实现路径完成? 例如,当我发送“ cd Do \ x09 \ x09”时,我会从远端收到两个答案:
def consist_at_least(start,points,min_points,window_size):
a = [point for point in points if start <= point <= start + window_size]
return len(a)>=min_points
points = [1.4,1.8,11.3,11.8,12.3,13.2,18.2,18.3,18.4,18.5]
min_points = 4
window_size = 3
total_interval = [0,20]
optional_starts = points + [item-window_size for item in points if item-window_size>=total_interval[0]] + [total_interval[0] + window_size] + [total_interval[1] - window_size] + [total_interval[0]]
optional_starts = [item for item in optional_starts if item<=total_interval[1]-window_size]
intervals = []
potential_ends = []
for start in sorted(optional_starts):
is_start_interval = len(intervals)%2 == 0
if consist_at_least(start,window_size):
if is_start_interval:
intervals.append(start)
else:
potential_ends.append(start)
elif len(potential_ends)>0 :
intervals.append(potential_ends[-1])
potential_ends = []
if len(potential_ends)>0:
intervals.append(potential_ends[-1])
print(intervals)
是否可以仅执行一个仅返回未完成命令的可能变体的命令?
这是我的代码:
[10.2,15.5,17]
解决方法
后台
我启动了WireShark以捕获流量。没有快速的方法可以解密SSH会话来分析数据包。但是我捕获了一个telnet会话并找到了解决方案。
关于终端机
终端如何工作? 每次使用SSH或Telnet连接到服务器时,当您按一个按钮时,它将自动发送到服务器,然后服务器以ACK消息答复,该消息包含已发送命令的副本。 假设您键入“ cd Do”,并且您想自动完成路径。每个字符都在单独的消息中发送:
- Client: "c"
- Server: "c"
- Client: "d"
- Server: "d"
以此类推。与空格字符相同。 当您按下TAB按钮时,您的终端会发送“ \t” control character 如果有多个选项,则将得到一个“ \ a” bell character,否则,将完成请求。如果您在当前目录中只有一个“下载”文件夹而没有“文档”文件夹,则该文件看起来像“ wnloads /”。 因此,第一次使用多个选项时,您会得到一个钟声。如果您再按一次TAB,终端将再发送一个“ \ t”字符,并且作为答复,服务器将发送两个数据包。第一个数据包包含“ \ r \ n”,第二个数据包包含两个数据字段,第一个数据包列出了我们可用的所有可能选项,第二个数据包使用命令返回提示行。示例:
Downloads/ Documents/ \r\n
root@ubuntu:/$ cd Do
因此,您只需要再输入几个字母即可使该选项唯一,然后点击TAB即可自动完成。
Python解决方案
点击TAB时,您需要:
- 将您的消息发送到服务器
chan.send("cd Do")
- 发送水平制表符
chan.send("\x09")
- 如果收到铃声,请再发送一个HT字符
chan.send("\x09")
- 打印输出。
- (如果您像我一样使用prompt_toolkit,则该选项是唯一的,并且从服务器接收到完成后,请使用我们的用户输入将默认值传递给提示符:
prompt('',default=str(interactive_cmd+output))
- 发送命令
chan.send("cd Downloads\r\n")