Lua中奇怪的io.popen行为

我在nginx配置文件中有一个lua代码块,用于检查redis服务器的连接以及4个Java进程是否运行,并根据这些检查返回200或500状态。

location = /healthcheck {

    content_by_lua_block {
        local redis = require "resty.redis"
        local red = redis:new()
        red:set_timeout(1000)
        local ok, err = red:connect("127.0.0.1", 6379)
        if not ok then
            ngx.status = 500
            return
        end

        local ps = io.popen("/bin/ps aux |grep -c '[j]ava.*63'")
        local output = tostring(ps:read('*a'))
        ps:close()
        if string.match(output, '4') then
            ngx.status = 200
        else
            ngx.status = 500
        end
    }

}

但是,有时候“output”变量会取到“nil”值,而本不应该。我真的不知道它“为什么会这样”。

非常感谢!

更新:

使用“tonumber”时会出错。

bad argument #2 to 'tonumber' (number expected, got string)

更新位置配置:

   location = /healthcheck {

        content_by_lua_block {
            local redis = require "resty.redis"
            local red = redis:new()
            red:set_timeout(1000)
            local ok, err = red:connect("127.0.0.1", 6379)
            if not ok then
                ngx.status = 500
                return
            end

            local ps = io.popen("/bin/ps aux |grep -c '[j]ava.*63'")
            local output = tonumber(ps:read())
            ps:close()
            if (output == 4) then
                ngx.status = 200
            else
                ngx.status = 500
            end
        }

    }

更新2:

使用 tostring 记录nginx错误信息:

grep: write error: Broken pipe
2016/04/19 17:54:48 [error] 301#0: *5 [lua] content_by_lua(healthcheck.conf:33):20: OUTPUT:nil

更新3:

使用命令grep -c '[j]ava.*63' <(/bin/ps aux)避免使用管道:

local ps = io.popen("grep -c '[j]ava.*63' <(/bin/ps aux)")

出现下面的错误提示:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `grep -c '[j]ava.*63' <(/bin/ps aux)'
点赞
用户3906452
用户3906452

根据 这个 回答和一些测试,下面的配置可以实现目标:

location = /healthcheck {

    content_by_lua_block {
        local redis = require "resty.redis"
        local red = redis:new()
        red:set_timeout(1000)
        local ok, err = red:connect("127.0.0.1", 6379)
        if not ok then
            ngx.status = 500
            return
        end

        local ps = io.popen("/bin/ps aux >/tmp/ps.out", "w")
        ps:close()
        local ps = io.popen("grep -c '[j]ava.*63' /tmp/ps.out")
        local output = tostring(ps:read())
        ps:close()
        if string.match(output, '4') then
            ngx.status = 200
        else
            ngx.status = 500
        end

    }

}
2016-04-19 15:34:02