I'm debugging some code, which is going to result in me constantly logging in / out of some external sftp servers. Does anyone know if paramiko automatically closes a ssh / sftp session on the external server if a non-paramiko exception is raised in the code? I can't find it in the docs and as the connections have to be made fairly early in each iteration I don't want to end up with 20 open connections.
Asked
Active
Viewed 5.2k times
3 Answers
46
SSHClient() can be used as a context manager, so you can do
with SSHClient() as ssh:
ssh.connect(...)
ssh.exec_command(...)
and not close manually.

Todor Buyukliev
- 561
- 4
- 3
-
3That's much better than `try: ... finally: ...`! – mimo Apr 06 '19 at 19:14
-
What if some exception is thrown during the execution of this? – runnerpaul Apr 29 '20 at 10:32
-
1@runnerpaul Context managers are designed to handle exactly that. No matter how you leave that block, be it normal execution, a `return`, an execution, anything, the connection will be closed. – undergroundmonorail Jun 05 '20 at 16:17
-
This should be the accepted answer. The `with` statement was introduced way back in [PEP 343](http://www.python.org/dev/peps/pep-0343/) in order to factor out try/finally statements. – Scott McAllister Apr 28 '21 at 14:26
-
How do you catch and handle exceptions? put the "with" inside of a try/except block? or put try/except inside the "with" block? – majorgear Nov 22 '22 at 15:55
34
No, paramiko will not automatically close the ssh / sftp session. It doesn't matter if the exception was generated by paramiko code or otherwise; there is nothing in the paramiko code that catches any exceptions and automatically closes them, so you have to do it yourself.
You can ensure that it gets closed by wrapping it in a try/finally block like so:
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()

aculich
- 14,545
- 9
- 64
- 71
-
Thank you, the problem was I was debugging a few thousand lines of code (and am still adding to it). The exceptions weren't being raised by paramiko but say by `subprocess` or `os` etc when something went wrong elsewhere. I guess that I could put a `client.close()` in every exception but that's not very pretty. – Ben Nov 29 '11 at 15:46
-
2If you put the calls to `subprocess` or `os` inside the `try` block then the `finally` block will always be called no matter what generated the exception. If you want it to be a little prettier then you might want to wrap client in a `Context Manager` and use the `with` statement. http://docs.python.org/reference/datamodel.html#context-managers – aculich Dec 09 '11 at 16:54
-
That sir is a point so +1! Doesn't answer the question and there's little point putting every individual thing in a `try ... finally` block if all the finally's are the same. But, there's nothing wrong with putting the call to the class inside one so I always close it cleanly. – Ben Dec 10 '11 at 22:28
-
How about posting the code (or a simplified version of it) and then it would be easier to say exactly what you need to do to not end up with 20 open connections. – aculich Dec 10 '11 at 23:07
-
I edited my answer to address your question more specifically... no, the connection does not automatically get closed by paramiko no matter where the exception was generated. – aculich Dec 10 '11 at 23:17
-
Excellent suggestion -- would only add a `client = None` before the try for completeness. – Marcel Wilson Jul 28 '16 at 18:31
0
As per documentation:
https://docs.paramiko.org/en/stable/api/client.html#paramiko.client.SSHClient.close
"(...) Failure to explicitly close your client after use may lead to end-of-process hangs!"

Quanzig
- 1
- 1
-
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/34605244) – Koedlt Jul 01 '23 at 07:49