我使用lua和luaposix库来获取某些命令的输出,有时候也会发送一些命令。我正在使用此代码或其中的变体来完成我的工作,但我有时会陷入posix.wait(cpid)
或有时命令似乎没有完成。
-- returns true on connected, else false
function wifi.wpa_supplicant_status()
-- iw dev wlan0-1 link
local r,w = posix.pipe()
local cpid = posix.fork()
if cpid == 0 then --child writes to pipe
--close unused read end
local devnull = posix.open("/dev/null", posix.O_RDWR)
posix.close(r)
posix.dup2(devnull, 0)
posix.dup2(w, 1)
posix.dup2(devnull, 2)
local dir = wifi.wpa_supplicant_dir()
local iface = posix.basename(dir)
iface = string.gsub(iface, "wpa_supplicant%-",'')
posix.exec('/usr/sbin/iw', {'dev', iface, 'link'})
posix._exit(-1)
elseif cpid > 0 then
--parent reads from pipe, close write end
posix.close(w)
local buf = ''
while true do
local tmp = posix.read(r, 100)
if tmp ~= nil and #tmp > 0 then
buf = buf .. tmp
else
break
end
end
-- TODO, check exit value, to see if entry exists or not
while posix.wait(cpid) ~= cpid do print("waiting in wpa_supplicant_status") end
print("status is "..buf)
if string.find(buf, "Connected to", 1, true) then
return true
else
return false
end
end
end
这就是我理解我必须做的事情(只是获得输出):
创建单个管道
叉
如果孩子,
关闭管道末端
dup2(write_end,stdout)
exec()到期望的过程
如果是父母
关闭管道末端
执行阻塞读取以读取管道末尾,直到读取0字节,这意味着子进程已终止,关闭管道
我错过了什么吗?
答案 0 :(得分:2)
您应该查看此问题How do you construct a read-write pipe with lua?
中的答案了解实施此问题的难度。令我印象深刻的是,似乎没有人能够只使用一个子进程来使用它。
但是,在你给出的例子中,似乎你只想得到命令的输出,所以我建议你这样做:
function os.capture(cmd)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
return s
end
function wifi.wpa_supplicant_status()
local dir = wifi.wpa_supplicant_dir()
local iface = posix.basename(dir):gsub("wpa_supplicant%-",'')
local cmd = ('/usr/sbin/iw dev %s link'):format(iface)
local buf = os.capture(cmd)
return buf:find("Connected to", 1, true) ~= nil
end
这甚至没有经过测试,但你应该明白这一点。