7
votes

Subprocess.Call n'attends pas que le processus complète

PAR PYTHON Documentation, Subprocess.Call doit bloquer et attendre que le sous-processus soit terminé. Dans ce code, j'essaie de convertir quelques fichiers xls vers un nouveau format en appelant libreoffice sur la ligne de commande. J'ai supposé que l'appel à l'appel de sous-traducrs bloque, mais semble être comme si je dois ajouter un délai artificiel après chaque appel, sinon quelques fichiers dans le répertoire .

Qu'est-ce que je fais mal? Et pourquoi ai-je besoin du délai? xxx

edit Il peut être difficile de trouver la réponse dans les commentaires ci-dessous. J'ai utilisé Unoconv pour la conversion de document qui bloque et facile à utiliser à partir d'un script.


2 commentaires

Depuis que vous avez 4 réponses, remplie de commentaires ici, permettez-moi de résumer les bases: appelle fait son travail et le problème est que libreoffice est simplement de retourner dès que Comme il indique au vrai programme de lancer la conversion. (Vous avez vérifié cela de la ligne de commande). Donc, ce que vous avez vraiment est une question de libreoffice: comment puis-je tirer un travail de conversion de la ligne de commande, puis attendez-vous qu'il finit? Vous aurez probablement une meilleure réponse à Ask.libreoffice.org qu'ici.


Simple Hack autour serait Donner à LibreOffice un peu de temps supplémentaire pour compléter le processus, ajouter une ligne de ligne.sleep (0.4), cela fonctionnerait.


3 Réponses :


5
votes

C'est possible probablement que libreoffice est implémenté comme une sorte de processus de démon / intermédiaire. Le "démon" sera (efficacement 1 ) analyser la ligne de commande, puis exploiter l'œuvre à un autre processus, éventuellement les détacher de manière à ce qu'il puisse quitter immédiatement. (Basé sur l'option -Visible dans le Documentation Je suppose fortement que c'est bien le cas que vous avez).

Si tel est le cas, alors votre sous-processus.Call fait ce qu'il est annoncé de faire - il attend que le démon complète avant de continuer. Cependant, cela ne fait pas ce que vous voulez, ce qui doit attendre que tout le travail soit terminé. La seule option que vous avez dans ce scénario consiste à voir si le démon a une option -Wait ou similaire.


1 Il est probable que nous n'avons pas de démon ici, seulement quelque chose qui se comporte de la même manière. Voir Commentaires par Abernert


8 commentaires

Je pense que tu as raison. Avez-vous une idée de la synchronisation avec un démon pour savoir si le travail est terminé?


@Kamyarsouri - Aucun indice. J'imagine que c'est une question spécifique de LibreOffice. Vous pourriez trouver une aide sur l'un de leurs forums.


En tant que note latérale, il est facile à tester s'il est utilisé comme démon. Il suffit d'émettre une commande qui devrait prendre beaucoup de temps à partir de la ligne de commande (par exemple, ouvrez une interface graphique). Si cela revient tout de suite, vous savez que vous avez un démon sur vos mains.


Je viens de tester ce que vous avez demandé. Il revient très rapidement, mais la sortie au terminal apparaît en quelques secondes.


Ce n'est probablement pas réellement un démon, mais un programme de lanceur qui démarre l'application GUI (s'il ne s'exécute pas) et lui indique d'ouvrir vos fichiers, puis de cesser de fumer. Mais l'effet est le même. Vous peut pour pouvoir exécuter l'application GUI actuelle directement, mais vous ne voudrez peut-être pas le faire.


@Abarnert - Peut-être que je ne connais-je pas ma terminologie ... Comment est-ce différent d'une "Démontion réelle"? :-P


@MGILSON: Parce qu'un démon de démon lui-même et continue à courir, au lieu d'envoyer un message à une autre application, puis de cesser de fumer. Le mettre en termes plus familiers, apachectl n'est pas un démon (mais httpd est, et c'est ce que apachectl contrôles). Le programme que libreoffice peut être exécuté ou non sous forme de démon, mais de chaque sens, libreoffice n'est probablement pas un.


@Abarnert - Je ne sais pas si ce étaient des termes plus familiers pour moi :-p, mais je pense que j'ai eu le point de toute façon. Merci d'avoir pris le temps d'expliquer.



0
votes

Si LibreOffice utilise un intermédiaire (démon) comme mentionné par @mgilson, une solution est de savoir quel programme il invoque, puis invoquer directement vous-même.


6 commentaires

Je n'ai pas de boîte de Linux à jour avec lo dessus, mais la façon dont son prédécesseur oo.o a fonctionné était que le programme de la VRAI GUI a été nommé soffice.bin , le programme de lancement était soffice et OpenOffice était juste un lien symbolique vers soffice . Et lancement soffice.bin a fonctionné directement comme exécutant firefox-bin au lieu de firefox . Ce qui signifie qu'il incendie une nouvelle interface graphique qui ne quitte pas après avoir terminé votre travail, elle est assise et attend que l'utilisateur appuie ^ q . C'est pourquoi j'ai dit "vous May être capable d'exécuter l'application GUI réelle directement, mais que vous ne voudrez peut-être pas le faire."


Si le programme de lanceur est assis et attend que l'utilisateur quitte, il n'y aurait pas de problème, non?


Je ne suis pas sûr. On dirait qu'il veut utiliser LO pour "convertir quelques fichiers" .xls "puis quitter (ou au moins le notifier au moins) quand c'est fait. Il peut y avoir un moyen de le faire avec des arguments de ligne de commande, mais il n'ya peut-être pas, auquel cas il ne s'agit que d'une partie de la solution.


@Abarnert - Ouais. On dirait que (si c'est le cas), il pourrait simplement utiliser le fait que -convert-to semble être une liste de fichiers.


@MGILSON: J'espérais cela (le lanceur ou la vraie application) avait une ligne de commande arguments de la ligne de commande "faire ces choses, puis quitter". Si cela fonctionne, c'est probablement la réponse la plus simple pour l'OP.


Oups, on dirait que c'est exactement ce que l'OP essayait de faire, et ça n'a pas fonctionné ...



3
votes

Le problème est que le soffice outil de ligne de commande (quel libreoffice est juste un lien vers ou une autre enveloppe autour) est juste un "contrôleur" pour Le programme réel soffice.bin . Il trouve une copie en cours d'exécution de soffice.bin et / ou crée sur, lui indique de faire du travail, puis quitte.

donc, appelle fait exactement la bonne chose: il attend libreoffice à cesser de fumer.

Mais vous ne voulez pas attendre libreoffice pour quitter, vous souhaitez attendre soffice.bin pour terminer faire le travail que libreoffice lui a demandé de faire.

Cela ressemble à ce que vous essayez de faire n'est pas possible de faire directement . Mais il est possible de faire indirectement .

Le Docs Dites ce mode sans tête:

... Permet d'utiliser l'application sans interface utilisateur.

Ce mode spécial peut être utilisé lorsque l'application est contrôlée par des clients externes via l'API.

En d'autres termes, l'application ne cesse pas après avoir exécuté certaines chaînes de l'ONU / faire des conversions / tout ce que vous spécifiez sur la ligne de commande, il est assis autour d'attendre plus de commandes de l'ONU de l'extérieur, tandis que le lanceur s'exécute dès que Comme il envoie les commandes appropriées à l'application.

Vous devez probablement utiliser l'API de contrôle externe mentionné ci-dessus (UNO) directement.

voir Scripting LibreOffice pour les bases (bien qu'il y ait plus d'informations sur les scripts internes que externes ), et le Documentation API pour plus de détails et exemples.

Mais il peut y avoir une réponse encore plus simple: Unoconv est un Un outil de ligne de commande simple écrit à l'aide de l'API UNO qui fait exactement ce que vous voulez. Il démarre LibreOffice si nécessaire, l'envoie des commandes, attend les résultats, puis cesse. Donc, si vous utilisez simplement Unoconv au lieu de libreoffice , appel est tout ce dont vous avez besoin.

remarquez également que Unoconv est écrit en python et est conçu pour être utilisé comme module. Si vous venez de importer , vous pouvez écrire votre propre code (plus simple et spécifique à la case) pour remplacer le " Entrée principale " CODE et NON UTILISEZ Subprocess du tout. (Ou bien sûr, vous pouvez déchirer vous-même le module et utiliser vous-même le code concerné vous-même, ou simplement l'utiliser comme une très belle pièce de code d'échantillon pour utiliser UNO de Python.)

En outre, le Unoconv La page liée ci-dessus répertorie une variété d'autres outils similaires, certains qui fonctionnent via UNO et certains qui ne fonctionnent pas, donc si cela ne fonctionne pas pour vous, essayez les autres. .

Si rien d'autre ne fonctionne, vous pouvez envisager, par exemple, créer un fichier Sentinel et utiliser une montre de système de fichiers, donc au moins vous pourrez détecter exactement quand il a terminé son travail, au lieu de deviner à un délai d'attente. Mais c'est une vraie solution de contournement du dernier fossé que vous ne devriez même pas envisager d'éliminer toutes les autres options.


7 commentaires

@Abarnert, j'ai également remarqué le - vs - mais cela ne fonctionne que pour moi si j'utilise - et avec - je reçois une erreur, je reçois une erreur de se plaindre de la fonte et de l'interface graphique qui me fait penser que cela n'a pas compris la ligne de commande paramètres. Je l'ai également essayé avec Soffice et j'ai le même résultat. Je génère le fichier XLS d'origine avec un script (à l'aide de XLWT) qui contient une formule. J'ai besoin d'ouvrir le fichier dans Excel pour évaluer les formules avant de les lire à nouveau avec un autre script. (XLWT n'évalue pas la formule). Je ne sais pas si Unoconv a le moteur d'évaluation ou non. Merci de toute façon pour votre réponse.


@Kamyarsouri: Unoconv n'a pas de moteur d'évaluation car il n'en a pas besoin. Il utilise l'API de script de l'UNO pour contrôler libreoffice, ce qui est l'évaluation réelle (et la conversion), ce qui correspond exactement à ce que vous voulez.


@Kamyarsouri: et, en regardant de plus près sur Unoconv , il est conçu pour être utilisé comme module. Donc, si vous ne pouvez pas l'utiliser simplement en l'exécutant via Subprocess , vous n'avez pas besoin de déchirer le tout et, juste importer le module et remplacer Le code "Entrée principale" avec vos propres trucs (simples, utilisateurs spécifiques à la case).


Je suppose que ce dont j'ai besoin est d'ouvrir et de sauvegarder le fichier dans LibreOffice pour lui donner une chance d'évaluer les cellules avec une formule. Sinon, lorsque j'ouvre le fichier de Python à l'aide de XLRD, ces cellules sont vides / non évaluées. Si UNOCONV n'évalue pas les cellules, il ne peut pas servir le but, non?


@Kamyarsouri: Comme je l'ai déjà expliqué, Unoconv utilise UNO pour ouvrir et enregistrer les fichiers de LibreOffice. Il n'a pas besoin d'évaluer les cellules elles-mêmes car elle n'ouvre même pas les fichiers lui-même. Il indique à LO d'ouvrir et d'enregistrer les fichiers, ce que vous voulez savoir exactement. Et évidemment lo fait savoir évaluer les cellules. Par conséquent, Unoconv fonctionnera.


J'ai essayé le Unoconv et il a fait le travail. Merci beaucoup pour vos réponses. affaire classée :)


OK cool. J'ai réécrit la réponse pour vous concentrer sur la partie pertinente au lieu de donner 20 possibilités différentes.