Seems to work pretty well. Your shell module in Lua then becomes very simple:
-- Non-blocking replacement for os.execute
local shell = {}
local sockproc_socket = "unix:/tmp/hello.sock"
function shell.execute(cmd, args)
local timeout = args and args.timeout
local input_data = args and args.data or ""
local sock = ngx.socket.tcp()
local ok, err = sock:connect(sockproc_socket)
if ok then
sock:settimeout(timeout or 15000)
sock:send(cmd .. "\r\n")
sock:send(string.format("%d\r\n", #input_data))
sock:send(input_data)
-- status code
local data, err, partial = sock:receive('*l')
if err then
return -1, nil, err
end
local code = string.match(data,"status:([-%d]+)") or -1
-- output stream
data, err, partial = sock:receive('*l')
if err then
return -1, nil, err
end
local n = tonumber(data) or 0
local out_bytes = n > 0 and sock:receive(n) or nil
-- error stream
data, err, partial = sock:receive('*l')
if err then
return -1, nil, err
end
n = tonumber(data) or 0
local err_bytes = n > 0 and sock:receive(n) or nil
sock:close()
return tonumber(code), out_bytes, err_bytes
end
return -2, nil, err
end
return shell