[英]The right way to close ssh connection when using pexpect?
我使用 Python pexpect(和 winpexpect)通過 ssh 執行命令
if platform.system() == 'Windows':
pexpectmodname = "winpexpect"
from winpexpect import winspawn as spawn
else:
pexpectmodname = "pexpect"
from pexpect import spawn
pexpectmod = __import__(pexpectmodname)
...
# connect
shellCmd = "ssh %s %d -l %s %s" % (portParam, port, username, server.host)
self.spawn = spawn(shellCmd, timeout=self.timeout, env=os.environ, ignore_sighup=False)
...
# DO WORK WITH SSH
...
# close ssh connection #1 (send exit)
self.spawn.sendline('exit')
index = self.spawn.expect([pexpectmod.EOF, "(?i)there are stopped jobs"])
if index == 1:
self.spawn.sendline("exit")
self.spawn.expect([pexpect.EOF])
# close ssh connection #2 (check isalive, send exit and close)
if self.spawn.isalive():
self.spawn.sendline('exit')
self.spawn.close()
# close ssh connection #3 (send sigkill)
import signal
self.spawn.kill(signal.SIGKILL)
如何關閉 self.spawn 以確保 ssh 會話已關閉? Windows 和 UNIX 的跨平台方式是什么?
優雅的方法是發送exit\\r
或CTRL-D
並等待EOF
。 但也可以在完成 SSH 會話后簡單地退出腳本(Expect、pexpect 或 winexpect)並且不關心 SSH 會話的退出狀態。 當腳本退出時(不管它是否干凈),操作系統內核會為您關閉 SSH 會話(TCP 連接)。 SSH 服務器不會抱怨這個。
pexpect.spawn.close()
將關閉 pty,后者又會將SIGHUP
發送到外殼,外殼會終止(殺死)外殼,除非外殼忽略SIGHUP
。 就像在 shell 仍在運行時關閉PuTTY
(或gnome-terminal
,...)窗口一樣。
上述語句假設所有應用程序(Expect、pexpect、winexpect 和 SSH 服務器)都得到了很好的實現。 我有一個系統 (ESXi),當 SSH 連接沒有完全關閉時,SSH服務器無法回收分配的 PTY。 因此,一段時間后,盡管 SSH 身份驗證成功,但我無法再獲得 PTY。
如果您的目標只是通過 SSH 執行命令,您還可以考慮使用Paramiko :
import paramiko
# Create a new client
client = paramiko.SSHClient()
# Connect to your remote
client.connect('127.0.0.1', username='john', password='doe')
# Execute a command
stdin, stdout, stderr = client.exec_command("pwd")
# Do anything you want with `stdout` and `stderr`
# Execute as many other commands as you want
# When you are done, close your connection
client.close()
它是一個純 Python 包,每當我使用它時都運行良好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.