我想编写一个程序(在Windows 7上使用Python 3.x),通过ssh在远程shell上执行多个命令。经过查看paramiko的exec_command()
函数,我意识到它不适用于我的用例(因为通道在命令执行后关闭),由于命令依赖于环境变量(由之前的命令设置),不能将它们连接成一个exec_command()
调用,因为它们要在程序中的不同时间执行。
因此,我想在同一个通道中执行命令。接下来我尝试了使用paramiko的invoke_shell()
函数实现交互式shell:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=user, password=psw, port=22)
channel = ssh.invoke_shell()
out = channel.recv(9999)
channel.send('cd mivne_final\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
channel.send('cd ..\n')
channel.send('cd or_fail\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
channel.send('cd ..\n')
channel.send('cd simulator\n')
channel.send('ls\n')
while not channel.recv_ready():
time.sleep(3)
out = channel.recv(9999)
print(out.decode("ascii"))
ssh.close()
这个代码存在一些问题:
- 第一个
print
并不总是打印ls
的输出(有时只在第二个print
中才打印出来)。 - 虽然我通过
recv
命令获取输出,但第一个cd
和ls
命令总是出现在输出中,而所有后续的cd
和ls
命令有时会被打印出来,有时则不会。 - 当被打印出来时,第二个和第三个
cd
和ls
命令总是出现在第一个ls
输出之前。
我对这种“非确定性”感到困惑,请您给予帮助,谢谢。
paramiko
吗?我发现使用fabric
更容易。你只需要设置env
变量,如user
、password
和host_string
,然后就可以做各种事情,比如使用get
从远程主机下载文件,使用put
发送文件,以及使用run
发出命令。你可以像这样链接命令:run('cd .. && cd simulator && ls')
。 - kchomskiinvoke_shell
意味着远程服务器可能会发送改变用户终端字体颜色等字符序列,清除这些混乱是一件麻烦的事情。 - chrisinmtown