2014-01-10 36 views
3

我正在使用Lua和luaposix庫來獲取某些命令的輸出,有時也會發送一些命令。我正在使用此代碼或這些代碼的變體來完成我的工作,但我有時會陷於posix.wait(cpid),或者有時該命令似乎並未完成。你如何正確使用帶有lua的管道來獲得程序的輸出?

-- 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 

這就是我明白我必須做的(只得到輸出):

  1. 創建一個單一的管

    • 如果孩子,

      1. 靠近讀管的端

      2. DUP2(write_end,標準輸出)

      3. EXEC()到期望的工藝

    • 如果父

      1. 靠近寫入管子末端

      2. 做阻塞讀取讀取管道的末端,直到你得到一個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 

這甚至不是測試,但你應該得到這個想法。