Bonjour,
ma question fait suite a mon interrogation précédente : http://linuxfr.org/forums/29/7788.html(...)
Je suis mis a étudier popen. sa a effectivement l'air de correspondre a mes attentes. Cependant j'ai quelques difficultés. Je vient d'essayer de le mettre en place avec une commande très simple un ping :
i, o=os.popen4('ping 192.168.0.1')
print o.readline()
Bon j'ai essayé un peu tout, lire une ligne utiliser read(),popen2 et popen3 .... Bon mais cette commande ne fini jamais.
J'ai l'impression que le ping étant toujours entrain de rajouter des lignes au fichiers il est impossible pour le readline() soit de commencer la lecture soit de la finir car il ne trouve pas le caractère de fin.
avez vous une solution et/ou une explication?
# man ping
Posté par mathieu mathieu (site web personnel) . Évalué à 1.
option:
-c count
Stop after sending (and receiving) count ECHO_RESPONSE packets.
# ping -c
Posté par SamG . Évalué à 2.
Si ta commande ping ne se termine jamais, o.readline() va toujours te renvoyer quelque chose (la commande est terminée quand o.readline() retourne '' ou None).
Pour résoudre ton problème, utilise l'option "-c 1" de ping pour arreter la commande après le 1er essai.
[^] # Re: ping -c
Posté par ferveuol . Évalué à 1.
Dans l'optique ou cette manipulation est impossible, il y a t il une méthode pour au moins récupérer d'une quelconque manière l'ID du sub-process?
[^] # Re: ping -c
Posté par Thomas Hervé . Évalué à 3.
Par exemple si tu fais :
i, o = os.popen2('top -b')
i.close()
o.readline()
# Tu fais les traitements nécessaires
o.close()
Là tu peux voir que la commande top c'est bien arrêtée. Ce n'est pas très clair comme principe, car ca dépend de la manière dont est gérée les sorties dans ton programme. A noter qu'un os.close(o.fileno()) peut mieux marcher dans certains cas (ne me demande pas pourquoi).
Si tu veux agir plus finement, il te faut le pid : regarde alors du coté du module popen2 sous python2.3 ou subprocess sous python2.4. Avec le pid tu peux envoyer les signaux que tu veux.
--
Thomas
[^] # Sa avance
Posté par ferveuol . Évalué à 0.
J'ai donc lancer ma commande avec popen2 et je récupère le file descriptor
j'utilise après un pattern écouteur ( si mes souvenir en design pattern son juste)
je crée un deuxième thread qui lit continuellement le fichier output de ma commande. En effet si je ne me trompe pas le "pseudo-fichier" n'a pas de caractère EOF par conséquent quand mon thread qui lit aura rattraper celui qui écrit il va attendre et ne quittera jamais sa fonction readline().
donc pour le moment sa donne ceci :
def run(self):
input, output=os.popen2('cd '+self.path+ ' && '+ self.path+'/'+self.name) #cmd a ecouter
input.close()
return output
def log(self, output):
import thread
tu = output, #création d'un tuple
th = thread.start_new_thread(viewlog, tu ) #lancement du thread de lecture
def viewlog( output): #thread qui lit
lin =output.readline()
while lin:
print lin
lin= output.readline()
Mon problème est maintenant au niveau du thread de lecture qui doit écrire sur mon terminal . Il n'écrit pas de manière continue il écrit lorsque j'appuie sur une touche. j'aimerais bien arrêter l'écoute sur l'appui d'une touche. je ne comprend pas pourquoi mon thread de lecture écrit de cette façon. avez-vous une explication? Que pensez-vous de ma méthode?
Je sais que je suis étreint de réaliser un truc un peu tordu. Mes explications sont sûrement confuse et je m'en excuse. dite vous que je veux réalisé un espèce de gestionnaire de démon capable de lancer/écouter/fermer un démon. *
Merci tout le monde pour l'aide que vous m'avez déjà apporté.
[^] # Re: Ca avance
Posté par Thomas Hervé . Évalué à 2.
En clair, tout dépend de la commande que tu lances. Peut -être que lire par caractères (avec read(x)) fonctionnera mieux dans ton cas.
--
Thomas
PS : ca serait encore plus plaisant de t'aider si tu faisais un petit effort d'orthographe/grammaire :)
[^] # Re: Ca avance
Posté par ferveuol . Évalué à 0.
PS : ca serait encore plus plaisant de t'aider si tu faisais un petit effort d'orthographe/grammaire :)
je suis désolais si je fait encore des erreurs sache que je suis dyslexique et que ne pas faire de faute et extrêmement dur pour moi. Je passe un correcteur d'orthographe sur chacun de mes messages. Il s'agit un correcteur en ligne qui vaut ce qui vaut c'est à dire pas grand chose. Je n'ai pas trouver de correcteur de grammaire en ligne mais si jamais quelqu'un en connais ça m'intéresse.
Sinon j'avais penser à la lecture caractère par caractère sa ne changer pas le problème. C'est pour sa j'utilise un thread pour la lecture c pour me permettre au niveau du thread supérieur de le tuer a la fin . Quand je travaillais sans ce thread je réussisse à lire la totalité et je resté bloquer a la fin . Je me suis dit que si je le mettais dans un thread je pourrai contrôler sont activité et l'arrêter a la fin.
Mais en fessant cela j'ai l'impression que le thread n'a pas la main pour écrire sur le terminal et qu'il l'obtient un cour instant quand j'appuie sur une touche
Je me demande si le fait que le thread qui lit et le thread qui écoute peuvent écrire dans le même terminal ne pose pas problème.
[^] # Re: Ca avance
Posté par Thomas Hervé . Évalué à 2.
OK excuse moi on voit trop souvent des personnes ici qui ne font certainement pas l'effort que tu fais.
Mais en fessant cela j'ai l'impression que le thread n'a pas la main
pour écrire sur le terminal et qu'il l'obtient un cour instant quand
j'appuie sur une touche
Je me demande si le fait que le thread qui lit et le thread qui écoute
peuvent écrire dans le même terminal ne pose pas problème.
C'est possible la gestion des threads est toujours sensible, mais en gros ca devrait fonctionner.
J'ai fait un petit exemple qui fonctionne chez moi (en m'inspirant de ton code):
import os
import thread
import time
def run(cmd):
input, output= os.popen2(cmd)
input.close()
return output
def log(output):
th = thread.start_new_thread(viewlog, (output,))
def viewlog(output):
lin = output.readline()
while lin:
print lin
lin = output.readline()
if __name__ == "__main__":
o = run("top -b")
log(o)
o = run("ping google.fr")
log(o)
while 1:
time.sleep(1)
print "wake"
Après les commande que je lance (ping et top) ne sont peut-être pas un bon exemple, mais ca montre que tu peux arriver à sortir des données depuis différents threads.
Si ton objectif est vraiment un contrôle de daemons, utiliser popen n'est pas le bon choix (il faut mieux utiliser un execv/fork et jouer avec les pids et les signaux). Si tu veux t'inspirer, il y a le module zdaemon de Zope qui fait quelque chose dans ce goût (browse, browse... ah : http://cvs.zope.org/Packages3/zdaemon/Attic/zdaemon.py(...) ).
Bon courage en tout cas.
--
Thomas
[^] # Re: Ca avance
Posté par ferveuol . Évalué à 0.
Je vais regarder au niveau de execv/fork je doit avouer que je connais pas trop ce genre manipulation avec les signaux et sa me fait un peu peur (bon mais comme je suis courageux...).
Sinon une dernière question: il est possible d'arrêter un programme lancer par le popen2 ?
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.