一. 使用方式见: Python之--paramiko实例
二. 遇到的问题
1. ssh.load_host_keys() takes exactly 2 arguments (1 given)
>>> ssh.load_host_keys()
Traceback (most recent call last):
File "", line 1, in
TypeError: load_host_keys() takes exactly 2 arguments (1 given)
解决方法: 指定known_hosts文件路径
>>> ssh.load_host_keys("/home/user/.ssh/known_hosts")
2. server IP not found in known_hosts
>>> ssh.connect(hostname=hostname, username=username, password=password)
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/dist-packages/paramiko/client.py", line 321, in connect
self._policy.missing_host_key(self, server_hostkey_name, server_key)
File "/usr/lib/python2.7/dist-packages/paramiko/client.py", line 85, in missing_host_key
raise SSHException('Server %r not found in known_hosts' % hostname)
paramiko.SSHException: Server not found in known_hosts
解决方法: 自动添加ip到known_hosts, 不用load系统文件
>>> ssh = paramiko.SSHClient()
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> ssh.connect(hostname=hostname, username=username, password=password)
3. FutureWarning: CTR mode needs counter parameter, not IV
>>> ssh.connect(hostname=hostname, username=username, password=password)
/usr/lib/python2.7/dist-packages/Crypto/Cipher/blockalgo.py:141: FutureWarning: CTR mode needs counter parameter, not IV
self._cipher = factory.new(key, *args, **kwargs)
解决方法参考:
Paramiko: “FutureWarning: CTR mode needs counter parameter”
Don't pass IV to pycrypto when using MODE_CTR #714
修改文件: /usr/lib/python2.7/dist-packages/paramiko/transport.py
elif name.endswith("-ctr"):
# CTR modes, we need a counter
counter = Counter.new(nbits=self._cipher_info[name]['block-size'] * 8, initial_value=util.inflate_long(iv, True))
# return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv, counter)
return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], '', counter)
else:
return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv)
4. stdout stderr均会出现log: paramiko.Channel 2 (closed)
>>> stdin, stdout, stderr = ssh.exec_command('touch /home/user/a.txt')
>>> print stdout
>>
解决方法: 命令写错了, 应该是:
>>> stdin, stdout, stderr = ssh.exec_command('touch /home/user/a.txt')
>>> print stdout.read()
5. 判断exec_command的返回值问题
stdin, stdout, stderr = ssh.exec_command('tail {}/log.txt* | grep "Finish process" | wc -l'.format())
assert stdout.read() == 1, "process didn't finished!"
以上代码在运行时, 即使log中有"Finish process", 也依然会抛出异常.
解决方法:
stdin, stdout, stderr = ssh.exec_command('tail {}/log.txt* | grep "Finish process" | wc -l'.format())
result = stdout.read()
assert '1' in result, "process didn't finished!"
因为stdout.read()实际上是"1\n", 所以判断语句改为 '1' in result.
且若写成 assert '1' in stdout.read() 也会抛出异常, 不知道为什么...