如何捕获Paramiko SFTPClient get()和put()的执行结果?
捕获SFTP传输的成功状态与错误信息
Paramiko的SFTPClient.get()和put()方法不会返回成功状态,但传输失败时会抛出异常,我们可以通过捕获这些异常来判断结果,并提取错误信息。以下是修改后的代码实现:
修改后的完整代码
import paramiko from ansible.module_utils.basic import * def get_sftp_client(host, port, user, password): try: # Open a transport transport = paramiko.Transport((host, port)) # Auth transport.connect(None, user, password) # Get a client object sftp = paramiko.SFTPClient.from_transport(transport) return (transport, sftp, None) except Exception as e: return (None, None, str(e)) def transfer_file(params): has_changed = False user = params['user'] password = params['password'] host = params['host'] port = params['port'] direction = params['direction'] src = params['src'] dest = params['dest'] transport, sftp, conn_error = get_sftp_client(host, port, user, password) if conn_error: meta = { "source": src, "destination": dest, "direction": direction, "stdout": None, "stderr": conn_error } return (has_changed, meta) stdout = None stderr = None try: if direction == 'download': sftp.get(src, dest) else: sftp.put(src, dest) has_changed = True # 传输成功则标记状态变更 except Exception as e: stderr = str(e) finally: # 确保资源被关闭 if sftp: sftp.close() if transport: transport.close() meta = { "source": src, "destination": dest, "direction": direction, "stdout": stdout, "stderr": stderr } return (has_changed, meta) def main(): fields = { "user": {"required": True, "type": "str"}, "password": {"required": True, "type": "str", "no_log": True}, "host": {"required": True, "type": "str"}, "port": {"type": "int", "default": 22}, "direction": { "type": "str", "choices": ["upload", "download"], "default": "upload", }, "src": {"type": "path", "required": True}, "dest": {"type": "path", "required": True}, } module = AnsibleModule(argument_spec=fields) # Do the work has_changed, result = transfer_file(module.params) # 如果有错误信息,返回失败状态 if result.get('stderr'): module.fail_json(msg="SFTP transfer failed", meta=result) module.exit_json(changed=has_changed, meta=result) if __name__ == '__main__': main()
关键修改说明
- 连接阶段异常捕获:修改
get_sftp_client函数,捕获连接/认证时的异常,返回错误信息,避免模块直接崩溃。 - 传输阶段异常捕获:将
get()/put()调用包裹在try-except块中,捕获所有传输相关异常,将错误信息存入stderr字段。 - 状态变更标记:传输成功时将
has_changed设为True,符合Ansible的状态变更逻辑。 - 错误处理流程:在
main函数中检查stderr字段,若存在错误则调用module.fail_json()返回失败结果,符合Ansible模块的错误输出规范。 - 资源安全关闭:使用
finally块确保SFTP客户端和Transport连接无论成功失败都会被关闭,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Chris F
相关产品推荐
相关产品推荐

