ブロックを積みながら(64) Node-RED、外部プログラムの実行ができるexecノード

Joseph Halfmoon

今回は execノード、出力が3個ある太っちょ(人のことは言えませんが)のノードです。外部プログラムを起動してその結果をとりこむことができるもの。テスト用の外部プログラムとしてはPythonのスクリプトを使用いたしました。標準出力、標準エラー出力、戻り値の3通りの方法で結果を受け取ることができます。

※「ブロックを積みながら」投稿順 index はこちら

まず外部プログラムとして走らせるためのPython3スクリプトを掲げます。特に意味のある動作をするわけでないのですが、異なる経路の出力、異なる戻り値を試すために以下のコマンドライン引数をとるようになっています。

    • –MES message文字列 このオプションの場合「message文字列」を標準出力に書き出します。戻り値としては0(ノーエラー)を返します。
    • -V このオプションを渡された場合、標準エラー出力に本コマンドのバージョン文字列を書き出します。戻り値としては1(エラー)を返します。
    • その他の引数もしくは引数なし 標準出力に Unknown Option と書き出し、戻り値2(エラー)を返します。

noderedExecTest.py

#! /usr/bin/python3
# coding: utf-8
import argparse
import sys

versionSTR = "noderedExecTest.py v0.0"

def errPrint(mes, opt=True):
    sys.stderr.write(mes)
    if opt:
        sys.stderr.write('\n')

def main():
    parser = argparse.ArgumentParser(description=versionSTR)
    parser.add_argument('--MES', nargs=1, help='Message.')
    parser.add_argument('-V', dest='VERSION', help='Show Version, then exit', action='store_true', default=False)
    args = parser.parse_args()
# VERSION
    if args.VERSION:
        errPrint(versionSTR, opt=False)
        sys.exit(1)
# Message
    if args.MES is not None:
        print(args.MES[0])
        sys.exit(0)
# Normal End
    print("Unknown option.")
    sys.exit(2)

if __name__ == "__main__":
    main()
実験用のフロー

execノードの入力にはInjectノードを3個接続してあります。それぞれのボタンを押したら上で説明した3種類のオプションをexecノードに与えるためです。

execノードの3個の出力にはそれぞれ debugノードを接続し、標準出力、標準エラー出力、戻り値に何が出てきているのか観察できるようにしてみました。

execTestFlow

execノードの設定

execノードの設定は以下です。

    • コマンドラインにはスクリプトファイル(実行可能属性与えてあります)をフルパスで記載。
    • 入力 msg の payload に載ってくる文字列を引数としてコマンドに与える
    • コマンドを実行し、終了時に出力を行う。
    • コマンドのタイムアウトはとりあえず10秒。

というところであります。こんな感じ。

execSettings

入力Injectノードの設定

念のため、Injectノードの設定も1個だけ示しておきます。単にコマンドライン引数となる文字列を payload に載せているだけ。

InjectMess

動作結果の確認

まずは –MES TEST をInjectノードから送り出した場合。以下のように文字列引数 TEST が、標準出力stdoutに送られています。文字列長が5であるのは改行文字が含まれているため。

戻り値は object 型のプロパティとして code : 0 が出力されてました。予定どおり。

MESresult

続いて、何もオプション文字列を送り出さなかった(空文字列)の場合。スクリプト内で生成された Unknown option 文字列が標準出力に送られ、戻り値のcodeには2が送られています。ここまではスクリプト側の働き。

それとは別に、戻り値のmsg には数字だけでなく、messageとしてフェイルを起こしたコマンドライン全体が載せられていました。codeがエラーを示すノンゼロだとexecノードが情報を付加してくれるようです。デバッグするときは便利かと。

NoOpResult

さて、最後は、-V オプションの場合。標準出力にはスクリプトは何も書き出してはいないのですが、空文字列がmsgに載ってやってきています。標準出力には空でも何かが実行された件だけは伝わるみたいですな。一方スクリプトが明示的に書き出している標準エラー出力(stderr)には予定どおりバージョン文字列が送られてきています。

戻り値側には、return code 1とともに、先ほど同様にフェイルしたコマンドライン、およびstderrに送ったバージョン文字列までmessageに載ってきています。

Vresult

また、エラー(戻り値がノンゼロ)の場合、カウントされてexecノードの下側にエラー件数が表示されました。こんな感じ。

ErrorRecognized

使い易いような気もしますが、本格的に使ったわけではないからね。どうなんだろ。

ブロックを積みながら(63) Node-RED、流量制限ができる、delayノード へ戻る

ブロックを積みながら(65) Node-RED、UDPパケットの送受信ノード へ進む