如何超时Paramiko sftp.put()与信号模块或在Python中的其他?

2022-04-04 00:00:00 python ssh sftp paramiko

问题描述

我希望函数sftp.put()超时,我已经尝试了Signal模块,但如果上传时间超过10s,脚本不会死。 我使用它通过ssh(Pariko)传输文件。

[...]
def handler(signum, frame):
        print 'Signal handler called with signal', signum
        raise IOError("Couldn't upload the fileeeeeeeeeeee!!!!")

[...]
raspi = paramiko.SSHClient()
raspi.set_missing_host_key_policy(paramiko.AutoAddPolicy())
raspi.connect(ip , username= "", password= "" , timeout=10)
sftp = raspi.open_sftp()        

[...]   
signal.signal(signal.SIGALRM, handler)
signal.alarm(10)

sftp.put(source, destination , callback=None, confirm=True)  
    
signal.alarm(0)
raspi.close()

[...]

更新1:

如果服务器停止响应一段时间,我希望中止传输。实际上,我的python脚本检查(在循环中)文件夹中的任何文件,并将其发送到这个远程服务器。但在这里的问题中,我想在服务器在传输过程中突然变得不可访问的情况下离开此功能(IP服务器更改,不再有互联网,...)。但当我模拟断开时,脚本停留在此函数sftp.put...)

更新2:

当服务器在传输过程中脱机时,Put()似乎永远被阻塞。这一行也会发生这种情况:

sftp.get_channel().settimeout(xx)

失去频道时怎么办?

更新3脚本目标

Ubuntu 18.04 和ParaMiko版本2.6.0

你好, 为了理解你的评论和问题,我必须提供更多关于我的丑陋剧本的细节,很抱歉:)

实际上,我不想手动终止一个线程并打开一个新线程。对于我的应用程序,我希望脚本完全自主运行,如果在过程中出现错误,它仍然可以继续运行。为此,我使用了Python异常处理。除了远程服务器在传输过程中关闭时,一切都按我所希望的那样进行:脚本在put()函数中被阻塞,我想是在一个循环中。 下面,脚本总共包含了3个函数,在您的帮助下超时,但显然没有什么可以离开这个该死的sftp.put()!你有什么新想法吗?

Import […]
[...]

def handler(signum, frame):
        print 'Signal handler called with signal', signum
        raise IOError("Couldn't upload the fileeeeeeeeeeee!!!!")

def check_time(size, file_size):
    global start_time
        if (time.time() - start_time) > 10:
            raise Exception

i = 0
while i == 0:

    try:

        
        time.sleep(1) # CPU break
        print ("go!")

        #collect ip server
        fichierIplist = open("/home/robert/Documents/iplist.txt", "r")
        file_lines = fichierIplist.readlines()
        fichierIplist.close()
        last_line = file_lines [len (file_lines)-1]
        lastKnowip = last_line

        data = glob.glob("/home/robert/Documents/data/*")   
        items = len(data) 

        if items != 0: 
        time.sleep(60) #anyway
            print("some Files!:)")
            raspi = paramiko.SSHClient()
            raspi.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            raspi.connect(lastKnowip, username= "", password= "" , timeout=10)

            for source in data: #Upload file by file    
                filename = os.path.basename(source) #
                destination = '/home/pi/Documents/pest/'+ filename #p

                sftp = raspi.open_sftp()

                signal.signal(signal.SIGALRM, handler)
                signal.alarm(10)

                sftp.get_channel().settimeout(10)
                start_time = time.time()

                sftp.put(source, destination, callback=check_time)

                sftp.close()    
                signal.alarm(0) 
            raspi.close()

        else:

            print("noFile!")

    except:
        pass

解决方案

尝试了很多东西后,在您的帮助和建议下,我找到了一个可靠的解决方案来满足我的需求。我在一个单独的线程中执行sftp.put,然后我的脚本就可以做我想做的事情。 非常感谢您的帮助

现在,如果服务器在传输过程中关闭,60秒后,我的脚本将继续使用:

[...]
import threading
[...]
th = threading.Thread(target=sftp.put, args=(source,destination))
th.start()                  
h.join(60)
[...]

相关文章