lua 中的奇怪 io.popen 行为
Strange io.popen behaviour in lua
我在 nginx 配置中有 lua 块,它检查 redis 服务器连接以及是否有 4 个 java 进程启动,然后 returns 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
值,而它不应该。就是不明白为什么会这样。
先谢谢战友们
UPD:
使用 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
}
}
UPD2:
记录到 nginx 错误(使用 tostring)打印下一个:
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
UPD3:
使用命令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)'
根据 this 回答和一些测试下一个配置做的工作:
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
}
}
我在 nginx 配置中有 lua 块,它检查 redis 服务器连接以及是否有 4 个 java 进程启动,然后 returns 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
值,而它不应该。就是不明白为什么会这样。
先谢谢战友们
UPD:
使用 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
}
}
UPD2:
记录到 nginx 错误(使用 tostring)打印下一个:
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
UPD3:
使用命令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)'
根据 this 回答和一些测试下一个配置做的工作:
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
}
}