Lua-скрипт не будет выполнять Python-скрипт - PullRequest
1 голос
/ 13 июня 2019

У меня есть скрипт lua, настроенный на запуск после отправки метаданных субъекта на определенный онлайн-сервер Orthanc.Я хочу, чтобы он очистил идентификатор субъекта, а затем вызвал скрипт Python с идентификатором в качестве аргумента.Когда я помещаю команду вручную в свой терминал, она работает, но сценарий lua, похоже, не выполняет ее.

Существует встроенная функция Orthanc, которая удаляет идентификатор субъекта, как только онотправлено на сервер.Первоначальный сценарий lua содержал следующее:

path = "/path/to/python_script.py"
os.execute("python " .. path .. " " .. subjectId)

Но сценарий не вызывался.

Сначала я хотел посмотреть, запускается ли он вообще, поэтому добавил:1008 *

file = io.open("/path/to/textfile.txt", "a")
file:write("\nI 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.

1 Ответ

1 голос
/ 13 июня 2019

Во-первых, чтобы ответить на ваш вопрос о проверке состояния из 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. Я также попытался воспроизвести вашу ситуацию с помощью простого теста, и у меня не было проблем с выполнением сценария Python с os.execute в сценарии Lua, расположенном в другом каталоге.

Для справки, это скрипт Lua с именем test.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\n", status)

    local num = 1
    for line in io.lines(filename) do
        printf("line %i = %s\n", 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; Затем скрипт Python просто выводит эти аргументы один за другим. Опять же, это был простой тест на подтверждение концепции.

Временный файл, созданный os.tmpname, должен быть в /tmp; Что касается ваших файлов, то есть ваших скриптов Lua и Python, вы должны точно знать, где находятся эти файлы. Надеюсь, что это может решить вашу проблему.

Кроме того, вы можете указать путь к скрипту Python - или любым другим необходимым файлам - к скрипту Lua в качестве аргументов командной строки, а затем слегка изменить существующий код.

$> ./test.lua path-to-python-file

Затем просто измените foo в test.lua, чтобы принять путь файла 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
...