17.4.1 指定コマンド実行の設定
ここでは,commandlineモジュールを使用して,指定したコマンドを実行する方法を説明します。
commandlineモジュールには,コンフィグレーションコマンドおよび運用コマンドをスクリプトから実行するCommandLineクラスがあります。CommandLineクラスのメソッド一覧を次の表に示します。
メソッド名 |
説明 |
---|---|
exec |
引数に指定したコマンドを実行します。 |
exit |
該当インスタンスによるコマンド実行を終了します。 |
set_default_timeout |
該当インスタンスによるコマンド実行時のデフォルトタイムアウト時間を設定します。 |
set_default_logging |
該当インスタンスから実行するコマンドのログを,運用コマンドshow loggingの表示対象とするかどうかのデフォルト値を設定します。 |
(1) スクリプトファイルおよび実行結果の例
(a) さまざまなコマンドを実行する例
さまざまなコマンドを実行するスクリプトファイルの例を次に示します。
# sample1.py # -*- coding: utf-8 -*- import extlib.commandline <-1 obj = extlib.commandline.CommandLine() <-2 # デフォルトタイムアウトの指定 obj.set_default_timeout(180) <-3 # コマンドログのshow loggingデフォルト非表示指定 obj.set_default_logging(extlib.commandline.DISABLE) <-4 # ユーザ応答なしコマンド(ls) print("ls start") dict_ret = obj.exec("ls") <-5 if dict_ret['result'] == extlib.commandline.OK: print(dict_ret['strings']) <-6 else: print("timeout.") # ユーザ応答ありコマンド(file1,file2の削除) print("rm start") dict_ret = obj.exec("rm -i file1 file2", ("?","y"), ("?", "y"), logging=extlib.commandline.ENABLE) <-7 if dict_ret['result'] == extlib.commandline.OK: print(dict_ret['strings']) <-8 else: print("timeout.") # コマンド応答タイムアウト時間指定(pingを3秒間実行) print("ping start") dict_ret = obj.exec("ping 192.0.2.1", 3) <-9 if dict_ret['result'] == extlib.commandline.TIMEOUT: print(dict_ret['strings']) <-10 obj.exit() <-11 |
-
モジュールをインポートします。
-
CommandLineクラスのインスタンスを生成します。
-
コマンド応答のデフォルトタイムアウト時間を指定します。
-
コマンドログのデフォルトのshow logging表示設定を非表示にします。
-
execメソッドで,実行するコマンド(ユーザ応答なし)を指定します。
-
コマンドの実行結果を出力します。
-
execメソッドで,実行するコマンド(ユーザ応答あり)とコマンドログのshow logging表示設定(表示する)を指定します。
-
コマンドの実行結果を出力します。
-
execメソッドで,実行するコマンドとコマンド応答のタイムアウト時間を指定します。
-
コマンドの実行結果を出力します。
-
コマンド実行状態を終了します。
スクリプトファイルsample1.pyの実行結果を次に示します。execメソッドで指定した運用コマンドls,rm,およびpingが,正しく実行されています。
# python sample1.py ls start file1 file2 rm start remove 'file1'? remove 'file2'? ping start PING 192.0.2.1 (192.0.2.1): 56 data bytes 64 bytes from 192.0.2.1: icmp_seq=0 ttl=63 time=0.377 ms 64 bytes from 192.0.2.1: icmp_seq=1 ttl=63 time=0.545 ms 64 bytes from 192.0.2.1: icmp_seq=2 ttl=63 time=1.349 ms 64 bytes from 192.0.2.1: icmp_seq=3 ttl=63 time=0.578 ms ----192.0.2.1 PING Statistics---- 4 packets transmitted, 4 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.377/0.858/1.385/0.445 ms # |
(b) スクリプト実行中にエラーが発生する例
コマンド応答のタイムアウト時間に,不正な値を指定した例を次に示します。
# sample2.py # -*- coding: utf-8 -*- import extlib.commandline <-1 obj = extlib.commandline.CommandLine() <-2 # コマンド応答タイムアウト時間指定(時間に負数を指定) print("ping start") dict_ret = obj.exec("ping 192.0.2.1", -3) <-3 print(dict_ret['strings']) <-4 obj.exit() <-5 |
-
モジュールをインポートします。
-
CommandLineクラスのインスタンスを生成します。
-
execメソッドで,実行するコマンドとコマンド応答のタイムアウト時間(負数)を指定します。
-
コマンドの実行結果を出力します。
-
コマンド実行状態を終了します。
スクリプトファイルsample2.pyの実行結果を次に示します。タイムアウト時間に指定した値が正しくないため,エラーになります。
# python sample2.py ping start Traceback (most recent call last): File "sample2.py", line 7, in <module> dict_ret = obj.exec("ping 192.0.2.1", -3) File "/usr/local/lib/python3.2/site-packages/extlib/commandline.py", line 741, in exec CNST.ERR_TIMER_INVALID)) ValueError: The timer value is invalid. # |
(c) コマンド実行失敗の例外が発生する例
execメソッドでコマンド実行失敗の例外が発生したときに,インスタンスを再生成する例を次に示します。
# sample3.py # -*- coding: utf-8 -*- import extlib.commandline <-1 obj = extlib.commandline.CommandLine() <-2 retry_cnt = 0 # ユーザ応答なしコマンド(ls) print("ls start") while retry_cnt < 3: try: dict_ret = obj.exec("ls") <-3 if dict_ret['result'] == extlib.commandline.OK: print(dict_ret['strings']) <-4 print("success!!") else: print("timeout.") break except extlib.commandline.ExecuteCommandError: <-5 obj.exit() <-6 obj = extlib.commandline.CommandLine() <-7 print("Regenerate the instance") retry_cnt = retry_cnt + 1 obj.exit() <-8 |
-
モジュールをインポートします。
-
CommandLineクラスのインスタンスを生成します。
-
execメソッドで,実行するコマンド(ユーザ応答なし)を指定します。
-
コマンドの実行結果を出力します。
-
execメソッドでのコマンド実行失敗の例外を捕捉します。
-
コマンド実行状態をいったん終了します。
-
CommandLineクラスのインスタンスを再生成します。
-
コマンド実行状態を終了します。
スクリプトファイルsample3.pyの実行結果を次に示します。例外が発生しても,インスタンスを再生成したため,運用コマンドlsが正しく実行されています。
# python sample3.py ls start Regenerate the instance file1 file2 success!! # |
(2) インスタンス生成
CommandLineクラスのインスタンスは,一つのプロセスに対して複数生成できません。インスタンスを再生成するときは,先に,既存のインスタンスに対してexitメソッドを呼び出してください。
(3) execメソッドでのコマンド実行
commandlineモジュールのexecメソッドを使用してコマンドを実行する場合,スクリプト専用ユーザ(ユーザ名script)によって該当コマンドが実行されます。execメソッドを使用したコマンド実行について次の表に示します。
項目 |
説明 |
---|---|
初期コマンド入力モード |
一般ユーザモード |
無効コマンド |
スクリプト専用ユーザでは,次に示す運用コマンドの実行による設定変更は無効となります。
また,スクリプト専用ユーザに対する次のコンフィグレーションコマンドは,パラメータエラー(illegal nameエラー)となります。
|
(4) コマンド承認
本装置にコマンド承認を設定している場合,スクリプトから実行するコマンドにもコマンド承認が適用されます。
スクリプトから実行するコマンドは,コンフィグレーションコマンドaaa authorization commands scriptのusernameパラメータで指定したユーザ名の権限で承認されます。なお,bypassパラメータを指定すると,コマンド承認をしないで無条件にコマンドを実行できます。
コマンド承認についての特記事項を次に示します。
-
aaa authorization commands scriptコマンドだけを設定しても,コマンド承認はしません。aaa authorization commandsコマンドをあわせて設定してください。ただし,RADIUSサーバによるコマンド承認はサポートしないため,TACACS+サーバまたはローカルによるコマンド承認の設定が必要です。
-
コンソール(RS232C)およびAUXで接続した運用端末からスクリプトを起動してコマンドを実行した場合のコマンド承認は,aaa authorization commands consoleコマンドの設定に従います。
- aaa authorization commands consoleコマンドの設定がある場合
-
コマンド承認の対象となります。ただし,bypassパラメータが設定されている場合は,コマンド承認をしないですべてのコマンドが実行できます。
- aaa authorization commands consoleコマンドの設定がない場合
-
コマンド承認をしません。すべてのコマンドが実行できます。
-
aaa authorization commandsコマンドの設定があり,コマンド承認情報(コマンドクラスまたはコマンドリスト)を取得できなかった場合は,すべてのコマンドが実行できません。コマンド承認情報を取得できない例を次に示します。
-
aaa authorization commands scriptコマンドの設定がない
-
指定したユーザ名が,TACACS+サーバまたはローカルに存在しない
-
TACACS+サーバにアクセスできない
-
-
コマンド承認情報(コマンドクラスまたはコマンドリスト)は,CommandLineクラスのインスタンス生成時に取得します。
-
コマンド承認を設定している場合,Python標準ライブラリのos.system()などによるプログラムの起動についても,起動制限の対象となります。プログラムを起動できるのは,次に示す場合だけです。
-
aaa authorization commandsコマンドの設定がない場合
-
aaa authorization commandsコマンドの設定があり,aaa authorization commands scriptコマンドのbypassパラメータの設定がある場合
-
aaa authorization commandsコマンドの設定があり,aaa authorization commands consoleコマンドの設定がなく,コンソール(RS232C)またはAUXで接続した運用端末から起動したスクリプトでプログラムを起動する場合
-