J'écris un wrapper à une commande externe ("sox", si cela peut aider) avec Perl "Tk". J'ai besoin de l'exécuter de manière asynchrone, bien sûr, pour éviter de bloquer le MainLoop de tk(). Mais, j'ai besoin de lire sa sortie pour informer l'utilisateur de la progression de la commande.Perl (tk): comment exécuter de manière asynchrone une commande système, en étant capable de réagir à sa sortie?
Je teste une solution comme celle-ci, en utilisant 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)
Mais bien sûr, les blocs de boucle while MainLoop jusqu'à cmd $ ne termine.
Existe-t-il un moyen de lire la poignée de sortie de manière asynchrone? Ou devrais-je utiliser des fourches standard? La solution devrait également fonctionner sous win32.
Tk :: IO semble emballer cette fonctionnalité dans un joli paquet; la documentation pour cela implique beaucoup de casse, mais j'ai utilisé une version piratée avec Expect pour contrôler les processus pendant un moment (wow, depuis 2005!). Y at-il quelque chose à ce sujet qui le rend impropre à l'utilisation? –
J'ai tendance à oublier 'Tk :: IO' - si cela fonctionne pour vous, alors c'est bien! En fait, il utilise '' fileevent' en interne, aussi, le tube est créé en utilisant 'open '- |" ', et la commande système est exécutée avec' exec', donc vous n'avez pas à vous inquiéter des erreurs X11 ici. –
Super! Je ne connaissais pas Tk :: fileevent ... Je pourrais forcer mon travail de code laid en insérant un appel "$ mw-> update" dans la boucle while, mais c'est définitivement une solution plus propre, que je vais tester dès que possible – MarcoS