I have a lua script which takes multiple inputs and I now want to run this lua script from a python program.
I used a subprocess to run the lua script and it works fine with one input.
python code:
import subprocess as sp
input_data: int = 5
p = sp.Popen(["lua-5.4.2\\lua54.exe", "test.lua"], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE, text=True)
result: str = p.communicate(input=str(input_data))[0]
Lua file:
local input = io.read()
local output = input * 10
print(output)
I now want to send multiple inputs to this lua script to do something like this:
import subprocess as sp
input_data_1: int = 5
input_data_2: int = 6
p = sp.Popen(["lua-5.4.2\\lua54.exe", "test.lua"], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE, text=True)
result: str = p.communicate(input=[str(input_data_1), str(input_data_2)[0]
local input_1 = io.read()
local input_2 = io.read()
local output = input_1 * input_2
print(output)
The problem is that the input
of p.communicate()
only takes strings.
i tried combining the inputs into a string and then separating them in the lua script but while it works, it's not really an elegant solution.
data = [5, 6]
data_str = (str(data).replace("'", "")
.replace(",", "")
.replace("[", "")
.replace("]", ""))
p = sp.Popen(["lua-5.4.2\\lua54.exe", "test.lua"], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE, text=True)
result = p.communicate(input=data_str)[0]
How can I do this better?
If you just want to send some numbers or strings, you can join them with line feed, then use lua's n
or l
flag to read these data.
p.communicate(input="5\n6.5\nhello\n7")
local input_1 = io.read('n') --5
local input_2 = io.read('n') --6.5
io.read('l') --'n' doesn't feed the '\n' after 6.5
local input_3 = io.read('l') --hello
local input_4 = io.read('n') --7
If you want to send complicated data, you can use python's struct + base64 modules for encoding and use lua's string.unpack function + base64 module for decoding. They use almost the same format, so it won't be very hard to learn. Let me show you an example to send 2 ints:
input_data = struct.pack('<ii', input_data_1, input_data_2)
input_data = base64.standard_b64encode(input_data).decode()
# ....
result: str = p.communicate(input=input_data)[0]
local base64 = require'base64'
local input = io.read('a')
input = base64.decode(input)
local input_1, input_2 = string.unpack('<ii', input)
Using json could be another option, but the same lua does not natively support it, you still need an external module.