Странное поведение io.popen в lua

У меня есть блок lua ​​в конфигурации nginx, который проверяет соединение с сервером 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
        }

    }

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

person cardinal-gray    schedule 18.04.2016    source источник
comment
Я проверил это, напечатав переменную в журнал nginx, и, насколько я помню, двойных кавычек не было.   -  person cardinal-gray    schedule 18.04.2016
comment
он возвращает строку nil или значение nil? почему вы все равно используете тостринг? чтение уже возвращает строку   -  person Piglet    schedule 18.04.2016
comment
Угадайте, переместите локальную строку ps = io.popen(...) в начало content_by_lua_block. Это что-то изменит?   -  person Alexander Altshuler    schedule 19.04.2016
comment
@AlexanderAltshuler Нет, это бесполезно. Я также пробовал tonumber, но печатает bad argument #2 to 'tonumber' (number expected, got string)   -  person cardinal-gray    schedule 19.04.2016
comment
popen используйте sh, а не bash, замена процесса не работает   -  person Alexander Altshuler    schedule 19.04.2016
comment
@AlexanderAltshuler проверьте мое (полагаю, рабочее) решение ниже, пожалуйста   -  person cardinal-gray    schedule 19.04.2016


Ответы (1)


В соответствии с этим ответом и некоторыми тестами следующей конфигурации:

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

    }

}
person cardinal-gray    schedule 19.04.2016
comment
@Prashanth какие-нибудь доказательства? Это РАБОТАЛО для меня около 3 лет назад. И, знаете, вещи меняются, так что, может быть, пока это не сработает. Может быть, если бы вы были более конкретными, кто-нибудь помог бы вам с вашей проблемой, чтобы она работала так, как вы хотите. - person cardinal-gray; 08.04.2019
comment
Привет, @cardinal-gray, я пытаюсь получить вывод своего сценария оболочки, но он не дает мне никакого вывода или даже не выдает ошибки. Он работает нормально, когда я запускаю `curl -I localhost:9001```, но не создает этот файл ps.out на во временном каталоге. - person Prashanth; 10.04.2019
comment
журнал_ошибок /var/log/nginx/error.log; события { worker_connections 1024; } http { сервер { слушать 9001; расположение /tmp { default_type text/html; content_by_lua ' ngx.say(‹p›привет, мир‹/p›) '; } location / { content_by_lua_block { 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) локальный вывод = tostring(ps:read()) ps:close() } } } } ``` - person Prashanth; 10.04.2019