Pythonにパラメーターを渡す
Pythonスクリプトは、単独で使用するか、RPGプログラムとともに使用するかにかかわらず、開発者に大きなメリットをもたらします。先日、Pythonを使用してあれこれ試していたところ、RPGプログラムからPythonスクリプトを実行することが必要になりました。また、スクリプトの実行だけでなく、Pythonにパラメーターを渡すことも必要となりました。
パラメーターを渡すことのメリットの1つは、プログラムまたはスクリプトをソフトコーディングすることが可能になることです。ソフトコーディングすることにより、プログラムの柔軟性および再利用可能性が向上し、メンテナンスの軽減に役立ちます。
それを行う方法を説明するために、非常に簡単なRPGプログラムと、さらに簡単なPythonスクリプトをコーディングしました。最初にPythonスクリプトを説明し、次いで、QShellを使用してRPGからそのスクリプトを実行する方法を説明します。
この記事で使用されているコードは、 ここからダウンロードできます。
まず、「sys」というPythonモジュールをインポートします(最初のコードを参照)。これで、端末に出力し、パラメーターを捕捉できるようになります。
import sys
次に示す残りのコードは、パラメーターを端末に出力するだけです。前述した通りで、実に簡単なスクリプトです。
print (sys.argv[0]) # prints the name of the Python script
print (sys.argv[1]) # prints parameter 1
print (sys.argv[2]) # prints parameter 2
print (sys.argv[3]) # prints parameter 3
print (sys.argv[4]) # prints parameter 4
スクリプトの結果を表示するために、ACSのSSH端末からスクリプトを実行します(図1. Pythonスクリプトを実行)。
ここでは、parameters1.pyというスクリプトを呼び出し、4つのパラメーター(lexie、slayer、yankees、two words)を渡しています。4つ目のパラメーターのtwo wordsをどうして引用符で囲んだのか疑問に思うかもしれません。これは、Pythonはスペースをパラメーターの終端と解釈するからです。4つ目のパラメーターを引用符で囲まなかったとしたら、Pythonはtwoとwordsを2つの別々のパラメーターと解釈し、4つではなく5つのパラメーターを渡したことになってしまいます。
結果を見てみると、「parameters1.py」という情報が追加されて端末に表示されているのに気付かれるかと思います。これは、Pythonスクリプトに実際に渡された1つ目の引数がスクリプトの名前であるからです。出力されたのは、引数0を出力するスクリプトをコーディングしたためです(図2のコードの1行目を参照)。
Pythonスクリプトが動作したら、どのようにすればRPGからこのスクリプトを実行できるのかについて見てみましょう。スクリプトに送ろうとしているパラメーター値を4つの変数に登録しました(以下のコードを参照)。本番プロセスでは、おそらくこれらはパラメーターとして渡されるか、表から取得されることになるでしょうが、ここでは、コード例を理解しやすくするためにハードコーディングしています。
dcl-s firstParameter char(10) inz('lexie');
dcl-s secondParameter char(10) inz('slayer');
dcl-s thirdParameter char(10) inz('yankees');
dcl-s fourthParameter char(10) inz('two words');
次に、Pythonスクリプトのパスとスクリプトの名前を定義します。
pathToPython = 'python3';
pythonScript = 'parameters1.py';
RPGプログラムの最後のパートは、QShellを呼び出してPythonスクリプトを実行します。
// Use Qshell to execute the Python script.
//
// Note: Parameters are detected by a space in Python, so the
// 'fourthParameter' needs to be in quotes since it has two
// words separated by a space. if I didn't put it in quotes,
// Python would see them as two separate parameters.
CmdStr = 'Qsh Cmd(' + quotes +
%trim(pathToPython) + ' ' +
%trim(pythonScript) + ' ' +
%trim(firstParameter) + ' ' +
%trim(secondParameter) + ' ' +
%trim(thirdParameter) + ' ' +
'"' + %trim(fourthParameter) + '"' + ''')';
Callp Run(Cmdstr:%Size(CmdStr));
コマンド ラインからRPGプログラムを呼び出すと、QShell端末を開いて結果が表示されます(図2. Pythonスクリプトの結果)。
直接Pythonスクリプトを実行したときと同じ結果を受け取りました。想定した通りのものです。
こうして、IBM iのコマンド ラインからRPGプログラムを実行したわけですが、何か他のことを試したらいい感じだろうと思います。SSH端末からRPGを呼び出すとしたらどうでしょうか。試してみましょう。
必要なのは、systemコマンドを実行して、RPGプログラム(Python_ex1)を呼び出すことだけです。Pythonスクリプトの結果が端末に出力されます(図3. SSH端末からRPGプログラムを呼び出す)。
いい感じではないでしょうか。
今回の例はかなりシンプルですが、RPGプログラムとPythonスクリプトの両方を一緒に使用する本番プロセスを構築するのに必要となるツールを手にしたことになります。本記事で使用されているPythonスクリプトおよびRPGプログラムのコード一式は、ダウンロードしてご利用いただけます。