Страницы

Поиск по вопросам

суббота, 7 декабря 2019 г.

Работа с stdin и stdout дочернего процесса одновременно в lua

#linux #lua #процесс #io


При написании lua скрипта наткнулся на одну вещь: io.popen, судя по документации
не может передать одновременно дескрипторы stdin и stdout запускаемого процесса.

Пример проблемного кода:

cmdexecute = function(cmd, input)
    local f = io.popen(cmd, "w");
    if tostring(input) ~= nil then
        f:write(tostring(input));
    end;
    local l = f:read("*a");
    f:close();
    return (l);
end;

if cmdexecute('xargs ps', 'aux') ~= nil then
    print 'ps aux что-то выдал';
else
    print 'ps aux промолчал';
end;


Результат выполнения:

Длинный-длинный вывод ps aux...
ps aux промолчал


А должно быть по идее:

ps aux что-то выдал


Вопрос: как получить дескрипторы и stdin, и stdout из popen? Или, возможно, есть
какое-то другое решение задачи, без io.popen?

Upd: по причине актуальности вопроса поясняю: решения с ffi допустимы.
    


Ответы

Ответ 1



Вам должен помочь модуль lua-subprocess Функция subprocess.popen принимает последним аргументом таблицу с именованными опциями. Среди них есть опции stdin, stdout и stderr, куда можно передать строку (имя файла), число (системный дескриптор файла), файловый объект или специальную константу subprocess.PIPE, которая создаст пайп для этого потока и сохранит его в возвращаемом объекте.

Ответ 2



io.popen дает интерфейс к системной posix функции popen, да, она может работать только в одну сторону. В вашем случае писать что то в ps не нужно. Если открыть ее для чтения - она конечно прочитает. Но я так понимаю ps у вас только для примера ... В POSIX для работы с обоими файловыми дескрипторами вызываемого процесса есть только 1 путь. Создание пар сокетов, привязка одного из концов этих соединений к файловым дескрипторам 0 и 1 (dup2). После чего выполняется fork и дочерний процесс вызывает нужную программу. В Lua судя по документации подобных средств не предусмотрено. Так что прямой ответ на ваш вопрос - получить и stdin и stdout одновременно невозможно. Из решений вижу только перенаправление вывода программы в файл и последующее чтение этого файла. Или ввод для программы пишется заранее в файл и подается на вход. И можно еще поэкспериментировать с именованными каналами. mkfifo создать именованный канал в файловой системе направить его в программу или запись из программы перенаправить в него и в lua открыть этот канал как обычный файл и попробовать писать/читать.

Комментариев нет:

Отправить комментарий