2011-08-23 37 views
9

Tôi đang gỡ lỗi một số mã, điều này sẽ dẫn đến việc tôi liên tục đăng nhập/thoát khỏi một số máy chủ sftp bên ngoài. Có ai biết nếu paramiko tự động đóng một phiên ssh/sftp trên máy chủ bên ngoài nếu một ngoại lệ phi paramiko được nêu ra trong mã? Tôi không thể tìm thấy nó trong các tài liệu và như các kết nối phải được thực hiện khá sớm trong mỗi lần lặp tôi không muốn kết thúc với 20 kết nối mở.Có paramiko đóng kết nối ssh trên một ngoại lệ không paramiko

Trả lời

15

Không, paramiko sẽ không tự động đóng phiên ssh/sftp. Nó không quan trọng nếu ngoại lệ được tạo ra bởi mã paramiko hay cách khác; không có gì trong mã paramiko bắt bất kỳ trường hợp ngoại lệ nào và tự động đóng chúng, vì vậy bạn phải tự làm điều đó.

Bạn có thể đảm bảo rằng nó được đóng lại bằng cách gói nó trong một thử/khối finally như vậy:

client = None 
try: 
    client = SSHClient() 
    client.load_system_host_keys() 
    client.connect('ssh.example.com') 
    stdin, stdout, stderr = client.exec_command('ls -l') 
finally: 
    if client: 
     client.close() 
+0

Cảm ơn bạn, vấn đề là tôi đã gỡ lỗi vài nghìn dòng mã (và vẫn đang thêm vào nó). Các ngoại lệ đã không được nâng lên bởi paramiko nhưng nói bởi 'subprocess' hoặc' os' vv khi một cái gì đó đã đi sai ở nơi khác. Tôi đoán rằng tôi có thể đặt một 'client.close()' trong mọi ngoại lệ nhưng điều đó không phải là rất đẹp. – Ben

+2

Nếu bạn đặt các cuộc gọi đến 'subprocess' hoặc' os' bên trong khối 'try' thì khối' finally' sẽ luôn được gọi là không có vấn đề gì tạo ra ngoại lệ. Nếu bạn muốn nó đẹp hơn một chút thì bạn có thể muốn bọc máy khách trong một 'Trình quản lý ngữ cảnh' và sử dụng câu lệnh' with'. http://docs.python.org/reference/datamodel.html#context-managers – aculich

+0

Thưa ông là điểm +1! Không trả lời câu hỏi và có ít điểm đặt mọi thứ riêng lẻ trong một khối 'try ... finally' nếu tất cả cuối cùng đều giống nhau. Nhưng, không có gì sai khi đưa cuộc gọi đến lớp bên trong nên tôi luôn luôn đóng nó một cách rõ ràng. – Ben

3

SSHClient() có thể được sử dụng như một nhà quản lý bối cảnh, vì vậy bạn có thể làm

with SSHClient() as ssh: 
    ssh.connect(...) 
    ssh.exec_command(...) 

và không đóng thủ công.

Các vấn đề liên quan