Во-первых, чтобы ответить на ваш вопрос о проверке состояния из 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