Python Paramiko SSHExceptionエラーの例外処理
- 評価
- クリップ 0
- VIEW 151
Pythonオブジェクト指向プログラミングは勉強の段階の身なのですが、以下ParamikoモジュールによるSSH接続と接続先の複数のLinuxサーバー上でコマンド実行し結果を返す処理を行うプログラムを知人の助けを借りて作成しました。(別txtファイルから接続先サーバーIPと実行コマンドを読み込む仕様です)
追加したい機能はSSH接続に失敗した際にエラー例外処理を行い、エラー内容とメッセージを出力後、処理を最後まで継続するように変更する事です。現在はSSH処理が失敗した段階で以降の処理が停止してしまう状態です。
https://www.programcreek.com/python/example/7495/paramiko.SSHException
上記ページを参照し試行錯誤してみてはみますが、オブジェクト指向で書かれた処理にどう綺麗に当該処理を加える事ができるのか今のところ上手くいっておりません。
ご教授の程よろしくお願いいたします。
YouheiSakurai様のご回答によりTimeoutError発生後も停止せずに以下任意のエラー出力と共に処理継続する事が確認できました!
SSH connection failed for xx.xx.xx.xxx ##
修正後のコード:
#Modules
import paramiko
from contextlib import suppress
from paramiko import SSHException
#Variables
USER = 'UserID'
PSWD = 'password'
#Classes and Functions
class InputReader:
def __init__(self, commands_path, hosts_path):
self.commands_path = commands_path
self.hosts_path = hosts_path
def read(self):
self.commands = self.__readlines(self.commands_path)
self.hosts = self.__readlines(self.hosts_path)
def __readlines(self, path):
with open(path) as f:
# return map(lambda v: v.strip(), f.readlines())
return [v.strip() for v in f.readlines()] #List comprehension
class CommandExecuter:
def __init__(self, host, command):
self.host = host
self.command = command
def execute(self):
with suppress(TimeoutError):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(self.host, username=USER, password=PSWD)
stdin, stdout, stderr = ssh.exec_command(self.command)
errors = stderr.readlines()
lines = [v.strip() for v in stdout.readlines()]
return lines
print('## SSH connection failed for %s ##' % h + '\n')
#Main Procedure
if __name__ == '__main__':
reader = InputReader("commands2.txt", "systems2.txt")
reader.read()
for h in reader.hosts:
for c in reader.commands:
executer = CommandExecuter(h, c)
results = executer.execute()
print("IP:{0}({1}):".format(h, c) + '\n')
if results != None:
for i in results:
print(i + '\n')
修正前のコード:
import paramiko
#Variables
USER = 'UserID'
PSWD = 'password'
#Classes and Functions
class InputReader:
def __init__(self, commands_path, hosts_path):
self.commands_path = commands_path
self.hosts_path = hosts_path
def read(self):
self.commands = self.__readlines(self.commands_path)
self.hosts = self.__readlines(self.hosts_path)
def __readlines(self, path):
with open(path) as f:
return [v.strip() for v in f.readlines()] #List comprehension
class CommandExecuter:
def __init__(self, host, command):
self.host = host
self.command = command
def execute(self):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(self.host, username=USER, password=PSWD)
stdin, stdout, stderr = ssh.exec_command(self.command)
errors = stderr.readlines()
'''if len(errors) != 0:
#raise Exception(errors)'''
lines = [v.strip() for v in stdout.readlines()]
#ssh.close()
return lines
#Main Procedure
if __name__ == '__main__':
reader = InputReader("commands.txt", "systems.txt")
reader.read()
for h in reader.hosts:
for c in reader.commands:
executer = CommandExecuter(h, c)
results = executer.execute()
print("{0}({1}):".format(h, c))
if results != None:
for i in results:
print(i)
print('\n')
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+2
contextlib.suppress
を使えば見通しよくエラーを無視できますよ
from contextlib import suppress
from paramiko import SSHException
with suppress(SSHException):
... # SSHに関する処理、例外が発生したらwithブロックを抜ける
print('とりあえずかんry')
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
check解決した方法
0
from contextlib import suppress
from paramiko import SSHException
上記contextlibのsuppressメソッドにより、あるホストに対するSSH接続タイムアウト処理発生時の処理を停止せず、エラーのみを出力するコードに変更できた。
修正後のコード添付済み
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 91.06%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/12/16 22:40
早速実装し、たま実行の結果ここにてご報告させて頂きます。
2017/12/17 00:12 編集