Я пишу обертку к внешней команде («sox», если это может помочь) с Perl «Tk». Мне нужно запустить его асинхронно, конечно, чтобы не блокировать MainLoop() tk tk. Но мне нужно прочитать его вывод, чтобы уведомить пользователя о прогрессе команды.Perl (tk): как запустить асинхронно системную команду, чтобы реагировать на ее вывод?
Я проверяю решение, как этот, используя IPC :: open3:
{
$| = 1;
$pid = open3(gensym, ">&STDERR", \*FH, $cmd) or error("Errore running command \"$cmd\"");
}
while (defined($ch = FH->getc)) {
notifyUser($ch) if ($ch =~ /$re/);
}
waitpid $pid, 0;
$retval = $? >> 8;
POSIX::close($_) for 3 .. 1024; # close all open handles (arbitrary upper bound)
Но, конечно, блоки цикла в то время как MainLoop до $ ЦМД это прекратить.
Есть ли способ считывать выходные данные асинхронно? Или я должен идти со стандартным вилкой? Решение также должно работать под win32.
Tk :: IO, кажется, завершает эту функциональность в приятном пакете; документация для него подразумевает много разломов, но я использовал взломанную версию с Expect для управления процессами на некоторое время (ничего себе, с 2005 года!). Есть ли что-то в этом, что делает его непригодным для использования? –
Я стараюсь забыть о 'Tk :: IO' - если это сработает для вас, тогда все в порядке! На самом деле, он также использует 'fileevent', труба создается с помощью' open '- | "', а системная команда выполняется с 'exec', поэтому вам не нужно беспокоиться о том, чтобы запустить здесь ошибки X11. –
Отлично! Я не знал о Tk :: fileevent ... Я мог заставить мою уродливую работу кода запускать вызов «$ mw-> update» в цикле while, но это определенно более чистое решение, которое я буду тестировать как можно скорее – MarcoS