使用python的paramiko包的RequirementParseError问题

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

2017-3-14碰到的两个问题。出现问题的机器是一台windows服务器,windows2008R2 standard 64位,Python2.7.9。

其实是两个问题夹杂在一起的,首先碰到的问题是:

No handlers could be found for logger "paramiko.transport"

这个问题和下面的第二个问题是夹杂在一起的。

问题的根源在于,测试代码中使用到了tornado的logger,root logger没有设置handlers,而针对'tornado.application'的logger设置了handlers(StreamHandler),所以需要修改测试代码,设置默认的root的handlers为NullHandler,而设置'tornado.application'的logger为StreamHandler。参考sysmgt项目中的test.py。(本质就是root logger没有设置handlers,导致其他logger因为继承它而也没有handlers,而只有唯一设置了的'tornado.application'这个logger可以正常输出)

 

第二个问题是在修复第一个问题后依然存在,错误(模拟测试)为:

D:\temp\py>python paramiko_test.py
test paramiko ........
time1 : [0.0] - 10.99.201.174 - wcadmin
time1 : [0.0] - 10.122.2.6 - wcadmin
time2 : [0.0] - 10.99.201.174 - wcadmin
time2 : [0.0] - 10.122.2.6 - wcadmin
time3 : [0.0] - 10.99.201.174 - wcadmin
time3 : [0.0] - 10.122.2.6 - wcadmin
time4 : [0.0] - 10.99.201.174 - wcadmin - 
time4 : [0.0] - 10.122.2.6 - wcadmin - 
--- ip=10.99.201.174, username=wcadmin, password=
--- ip=10.122.2.6, username=wcadmin, password=
Traceback (most recent call last):
  File "paramiko_test.py", line 42, in one_connection
    sshclient.connect(ip, 22, username, password)
  File "C:\app\Python27\lib\site-packages\paramiko\client.py", line 338, in connect
    t.start_client(timeout=timeout)
  File "C:\app\Python27\lib\site-packages\paramiko\transport.py", line 500, in start_client
    raise e
RequirementParseError: Invalid requirement, parse error at "''"
time5 : [0.452000141144] - 10.99.201.174 - wcadmin
time6 : [0.46799993515] - 10.99.201.174 - wcadmin

上面是测试程序(多线程连接远程服务器)的测试结果。同样的程序在我自己电脑没有问题。

RequirementParseError: Invalid requirement 这个问题不是每次运行测试程序都会出错,出错的概率感觉在85%。

解决过程:

1 怀疑过时pip版本的问题,最后卸载后又安装。因为没找到老版本的pip,所以pip前后都是新版本。后来证明了这跟pip无关。

2 怀疑paramiko的版本问题,将paramiko由1.*升级到2+。依然有问题。

3 根据网上类似问题,是说是setuptools库的问题,卸载,然后安装,报找不到模块appdirs。下载并安装模块appdirs。然后安装新版本的setuptools,即解决该问题。

老的setuptools的版本为22.0.0,而新安装的是34.3.2.。我本机的版本为16.0。所以看来是setuptools某个版本与paramiko冲突。将服务器上的setuptools版本降级,问题解决。

3.15日,发现服务器上setuptools虽然降级当时测试没问题,实际是没有深入测试,线程并发多了后还是有同样的问题。

于是将我本机的setuptools卸载后安装最新版本,复现了服务器上的问题。在Linux机器上测试,setuptools在高版本时也有问题。接下来找到一篇文章,说将setuptools的版本降到20.2一下。所以最后采用19.7这个版本,经过测试没有问题。

不知道问题会不会复现,再看吧。

 

3.15日,在服务器端反复安装卸载setuptools和pip,发现一些情况,不是特别明白。

1 pkg_resources这个模块,查阅资料,应该是加载模块用的,在python安装后它出现在$python_home/Lib/site-packages下,当时有时安装最新的pip和setuptools后发现在site-packages下的pkg_resources不在了,而出现在setuptools中。

2 在多次安装卸载pip setuptools后发现pip.exe和pip-script.py不见了,导致pip不能用,因为操作多次,不知道是哪次出现这个问题,只好把其他机器上这两个文件拿来用。不知道其他文件是否也丢失。

针对第二个问题,在网上找到一个办法,执行下面命令:

python -m pip install --upgrade pip --force-reinstall

 

本文发表于开源中国OSCHINA,当时以为已经解决了问题,结果第二天问题依然存在,结果就在网上继续搜索,发现本文已经被某网站转载,我估计是通过网页爬虫抓取自动发表,所以今日更新,过几天看看是否还会被爬取:)。

我的测试程序:

#-*-coding:UTF-8-*-

__author__='zhaoxp'

import traceback
import logging
import time
import threading

import paramiko

logging.basicConfig(level=logging.DEBUG)
logging.getLogger().handlers=[logging.NullHandler()]
logger = logging.getLogger('paramiko.test')
logger.handlers.append(logging.StreamHandler())
logger.setLevel(logging.DEBUG)

def main():
    threads = []
    threads.append(threading.Thread(target=one_connection, args=('10.99.201.174', 'wcadmin', 'password')))
    threads.append(threading.Thread(target=one_connection, args=('10.122.2.6', 'wcadmin', 'password')))
    threads.append(threading.Thread(target=one_connection, args=('10.99.201.37', 'wcadmin', 'password')))
    threads.append(threading.Thread(target=one_connection, args=('10.99.244.121', 'wcadmin', 'password')))
    for th in threads:
        th.start()
    for th in threads:
        th.join()


def one_connection(ip, username, password):
    sshclient = None
    try:
        start_time = time.time()
        logger.debug('time1 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
        sshclient=paramiko.SSHClient()
        logger.debug('time2 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
        sshclient.load_system_host_keys()
        logger.debug('time3 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
        sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        logger.debug('time4 : [%s] - %s - %s - %s'%(time.time()-start_time, ip, username, password))
        logger.debug('--- ip=%s, username=%s, password=%s'%(ip, username, password))
        sshclient.connect(ip, 22, username, password)
        logger.debug('time5 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
        stdin, stdout, stderr = sshclient.exec_command('pwd')
        #logger.debug('stdout:\n%s \n stderr:\n%s \n'%(stdout.read(), stderr.read()))
        logger.debug('time6 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
    except BaseException as be:
        traceback.print_exc()
    finally:
        if sshclient is not None:
            sshclient.close()

if __name__=='__main__':
    print 'test paramiko ........'
    main()

 

转载于:https://my.oschina.net/shawnplaying/blog/858706

你可能感兴趣的:(使用python的paramiko包的RequirementParseError问题)