LuaスクリプトはPythonスクリプトを実行しません
件名のメタデータが特定のオンラインOrthancサーバーに送信されると、トリガーするように設定されたluaスクリプトがあります。私はそれが件名IDをスクラップし、引数としてIDを持つPythonスクリプトを呼び出すようにしたい。コマンドを手動で端末に入れると動作しますが、luaスクリプトは実行されていないようです。
サーバーに送信されると、サブジェクトからIDをスクラップする built-Orthanc 関数があります。 最初のluaスクリプトには次のものがありました:
path = “/path/to/python_script.py”
os.execute(“python ” .. path .. ” ” .. subjectId)
しかし、スクリプトは呼び出されていませんでした。
私は最初にそれがトリガーされているかどうかを確認したかったので、私は追加しました:
file = io.open(“/path/to/textfile.txt”, “a”)
file:write(”
I am alive, subjectId is ” .. subjectId)
file:close()
それはうまくいった!
だから私はos.executeに何か問題があるかどうかを見たかったので、私はしました:
os.execute(“touch /same/path/deleteme.txt”)
それはうまくいった。 したがって、os.executeが機能していないようです。 スクリプトが呼び出されない理由は誰にも分かりますか?
編集:誰もos.executeコマンドのステータスをチェックする方法を知っていますか? 編集:私はPython 3.5.6、Lua 5.1.4、およびLinuxを使用しています。
まず、os.executeからのステータスのチェックについて質問します。この関数はa status code, which is system dependent( https://www.lua.org/manual/5.1/manual.html#pdf-os.execute )を返します。このステータスコードを記録して無効なコマンドを処理しようとしましたが、多少役に立たないことがわかりました。さらに、シェル自体はエラーメッセージを出力しました。
os.execute(“hello”) — ‘hello’ is not a shell command.
> sh: 1: hello: not found
シェルからのこのエラーメッセージは、私のLuaスクリプトによって捕捉されて読み込まれていませんでしたが、代わりにstderrに直接送信されていました。 (それについての良い参照: https://www.jstorimer.com/blogs/workingwithcode/7766119-when-to-use-stderr-instead-of-stdout )。
一時ファイルを使用してエラー出力をキャッチするための興味深い解決策を見つけました。
tmpname = os.tmpname()
os.execute(string.format(“hello 2> %s”, tmpname))
for line in io.lines(tmpname) do
print(“line = ” .. line)
end
これは以前に説明したエラーであるline = sh: 1: hello: not foundを出力します。 os.executeは、次のようなコマンドのステータスも返します。
a, b, c = os.execute(“echo hello”)
> hello
print(a, b, c)
> true exit 0
d, e, f = os.execute(“hello”) — An invalid command
> sh: 1: hello: not found
print(d, e, f)
> nil exit 127
この例では、cとfはそれぞれのコマンドの終了ステータスです。前のコマンド、つまりPythonスクリプトの実行に失敗した場合、終了ステータスは非ゼロでなければなりません。
Pythonに関するあなたの主な質問に対処するために、私はスクリプトへのパスを二重にチェックします – 常に単純な健全性チェックから始める良いアイデアです。 string.formatを使用して次のようなコマンドをアセンブルすることを検討してください。
command = string.format(“python %s %i”, tostring(path), tonumber(subjectId))
os.execute(command)
また、使用しているLua/Pythonのバージョンと、おそらくあなたのシステムも知っておくと便利です。
編集:あなたがそれらを少し残す必要があるかどうかに応じて、os.tmpnameで生成された一時ファイルをos.removeで削除する必要があります。私はまた、単純なテストであなたの状況を再現しようとしましたが、別のディレクトリにあるLuaスクリプトでos.executeでPythonスクリプトを実行するのに問題はありませんでした。
参考までに、これはtest.luaと呼ばれるLuaスクリプトで、/tmp/throwawayという一時ディレクトリに作成しました。
#!/usr/bin/lua
local PATH_TO_PY_FILE = “/tmp/py/foo.py”
local function fprintf(fil, formal_arg, …)
fil:write(string.format(formal_arg, …))
return
end
local function printf(formal_arg, …)
io.stdout:write(string.format(formal_arg, …))
return
end
local function foo(…)
local t = {…}
local cmd = string.format(“python3 %s %s”, PATH_TO_PY_FILE, table.concat(t, ” “))
local filename = os.tmpname()
local a, b, status = os.execute(string.format(“%s 2> %s”, cmd, filename))
printf(“status = %i
“, status)
local num = 1
for line in io.lines(filename) do
printf(“line %i = %s
“, num line)
num = num + 1
end
os.remove(filename)
return
end
local function main(argc, argv)
foo()
foo(“hello”, “there,”, “friend”)
return 0
end
main(#arg, arg)
(私のCスタイルの主な機能を許してください、ハハ。)
/tmp/pyという別の一時ディレクトリで、次のようなPythonファイルを作成しました。
import sys
def main():
for arg in sys.argv:
print(arg)
if __name__ == ‘__main__’:
main()
Luaスクリプトの関数fooは可変数の引数をとり、Pythonスクリプトにcommand-line引数として提供します。 Pythonスクリプトは、それらの引数をone-by-oneだけ出力します。繰り返しますが、これは概念証明のための単純なテストでした。
os.tmpnameによって作成された一時ファイルは/tmpになければなりません。あなたのファイル、つまりあなたのLuaとPythonスクリプトのように、あなたはそれらのファイルがどこにあるのか正確に知っていることを確認します。うまくいけば、それはあなたの問題を解決することができます。
また、Pythonスクリプトへのパスやその他の必要なファイルをコマンドライン引数としてLuaスクリプトに渡し、既存のコードをわずかに修正することもできます。
$> ./test.lua path-to-python-file
次に、test.luaのfooを変更して、Pythonファイルのパスを引数として受け入れます。
local function foo(py_path, …)
local t = {…}
local cmd = string.format(“python3 %s %s”, py_path, table.concat(t, ” “))
— Everything else should remain the same.
end
source