#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 открыть этот канал как обычный файл и попробовать писать/читать.
Комментариев нет:
Отправить комментарий