IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Démarrer et arrêter un script depuis un autre (daemon?)


Sujet :

Langage Perl

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2007
    Messages : 12
    Points : 7
    Points
    7
    Par défaut Démarrer et arrêter un script depuis un autre (daemon?)
    Bonjour à tous,

    J'ai déjà lu quelques sujets sur le forum à ce propos, mais je n'y trouve pas ma réponse.

    Depuis un script, je désire en démarrer un autre, sans que ca n'interrompe le premier. Par la suite, j'aimerais également pouvoir arrêter le script.

    Si j'ai bien compris, il s'agit de faire un fork. Cependant, je n'arrive pas à mon but.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    sub startprog {
     FORK:{
        my $pid;
        if ($pid=fork) {
    	return "start";
        } elsif (defined $pid) {
          system('perl monprog.pl');
          exit(0);
        } else {
          return -1;
        }
      }
    }
    En effet, ce code démarre bien mon script monprog.pl, mais ne continue pas le script parent (n'affiche pas start tant que monprog.pl fonctionne).

    Le terminal qui s'ouvre pour monprog.pl s'affiche en premier plan, y'a-t-il un moyen de masquer la fenetre en arrière plan?

    Pouvez-vous me donner des pistes pour l'arrêt du programme ?

    Petite précision peut-être utile : je travaille sous ActivePerl (Windows).

    Merci d'avance! Et bon week-end!

    Lily

  2. #2
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    A mon avis, il te manque un waitpid(), regarde là dans la FAQ.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2007
    Messages : 12
    Points : 7
    Points
    7
    Par défaut
    Merci pour ta réponse!

    J'ai lu la FAQ, mais le problème, c'est que je ne veux justement pas que mon processus père attende la fin du processus fils. Si j'ai bien compris, le waitpid attend la fin du fils. Or, j'aimerais qu'au moment ou le processus fils démarre, le processus père affiche "start". Donc que mes deux processus fonctionnent en parallèle, sans attendre la fin l'un de l'autre.

  4. #4
    Membre chevronné
    Avatar de Woufeil
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 1 076
    Points : 2 004
    Points
    2 004
    Par défaut
    Salut,

    Ce que tu pourrais faire, c'est utiliser les threads pour ce genre de choses :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    use threads;
     
    my $thr=threads->new( sub {system('perl monprog.pl')} ); #Générer le thread
    $thr->detach; #Indique qu'on ignore le trhead thr
     
    #actions
    Dis nous si ce code te convient

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2007
    Messages : 12
    Points : 7
    Points
    7
    Par défaut
    Merci!

    J'ai testé, mais je n'arrive toujours pas à mon résultat espéré

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sub startprog {
     
    my $cmd = 'perl monprog.pl';
     
    my $thr=threads->new( sub {exec($cmd)} ); #Générer le thread
    $thr->detach; #Indique qu'on ignore le trhead thr
     
    return "start";
     
    }
    Maintenant j'ai le "start" qui s'affiche, mais monprog.pl n'est plus executé. Pouvez-vous m'éclairer ? Merci!

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2007
    Messages : 12
    Points : 7
    Points
    7
    Par défaut
    En faisant divers tests, je m'appercois que mon programme s'execute de la même façon que je fasse le fork ou non.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sub startprog {
     
    my $cmd = 'perl monprog.pl';
     
    	system($cmd);
     
    return "Start";
     
    }
    Ce code produit exactement la meme chose que celui que j'ai montré au début du sujet. Cela signifie donc que le fork ne fonctionne pas ? Quelqu'un peut-il m'expliquer ?

    Merci!

  7. #7
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 39
    Points : 30
    Points
    30
    Par défaut
    Il te suffit de lancer le script en tache de fond comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    system ("commande param1 param2 &") ;
    Il est important que tu passes tes paramètres avec la commande dans une seule chaine de caractère et non pas sous forme de liste, faute de quoi il n'y aura pas d'interprétation par le shell, et donc le script ne sera pas lancé en arrière plan ...

  8. #8
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par ankou29666 Voir le message
    Il te suffit de lancer le script en tache de fond comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    system ("commande param1 param2 &") ;
    Il est important que tu passes tes paramètres avec la commande dans une seule chaine de caractère et non pas sous forme de liste, faute de quoi il n'y aura pas d'interprétation par le shell, et donc le script ne sera pas lancé en arrière plan ...
    Oui, enfin sous Windows ça marche moins bien...

    Bon par ailleurs pour ce qui est de la solution par thread, il ne faut pas que tu le détaches, car en Perl quand le thread principal meurt, les autres threads meurent avec lui. Fait plutôt un join() à la fin de ton script.

    --
    Jedaï

  9. #9
    Membre chevronné
    Avatar de Woufeil
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 1 076
    Points : 2 004
    Points
    2 004
    Par défaut
    Oups, je croyait que justement en utilisant detach on évitait ce comportement

  10. #10
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par Woufeil Voir le message
    Oups, je croyait que justement en utilisant detach on évitait ce comportement
    Et bien ça serait logique et dans une implémentation plus classique des threads tu aurais sûrement raison, malheureusement les threads en Perl n'ont rien de classique donc detach() sert uniquement à s'éviter un join() quand on ne se soucie pas de la valeur retournée ET quand on est sûr que le thread principal durera suffisamment longtemps (ou que l'on ne se soucie pas que le thread detach()é finisse).

    --
    Jedaï

  11. #11
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 39
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par Jedai Voir le message
    Oui, enfin sous Windows ça marche moins bien...
    Euh oui en effet ... ça fait tellement longtemps que j'ai plus utilisé windows que par moment j'en oublie même que ça existe ...



    par contre, en relisant bien le sujet, il faut également pouvoir arréter le script tournant en tache de fond ... je n'ai jamais trouvé le moyen de tuer un thread, étant donné que je n'ai trouvé aucun moyen de récupérer le pid d'un thread, et qu'il est indispensable pour pouvoir le tuer avec kill ...

    il faudrait donc à priori revenir à une solution à base de fork et laisser tomber les threads ...

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2007
    Messages : 12
    Points : 7
    Points
    7
    Par défaut
    Je vous remercie tous pour vos réponses!

    Eh oui, je sais Windows, c'est mal! Malheureusement pour le moment je dois faire avec

    Comme ankou l'a dit, les threads me permettent pas d'arrêter le processus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
     
    sub start {
     
    my $cmd = 'perl monprog.pl';
     
    FORK:{
        my $pid;
        if ($pid=fork) {
    	return "start";
        } elsif (defined $pid) {
    	system($cmd);
        } else {
          return -1;
        }
      }
    }
     
    sub stop {
    my $cmd = 'kill -9 0';
    system($cmd);
    return "Arrêt";
    }
    J'en suis donc restée au fork. Mais... ca ne semble pas fonctionner! En tout cas, le kill ne tue pas mon processus monprog.pl.
    (monprog.pl tourne en boucle indéfiniement, je dois donc le tuer!)

    Pourquoi cela ne fonctionne pas ? Spécialité de Windows ou faute du code ?

    Sinon tant pis, l'arrêt du programme se fera manuellement en cliquant sur la petite croix en haut à droite!

    Encore merci à tous pour votre aide!

  13. #13
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    kill n'est pas une commande shell windows, par contre la fonction kill() de Perl devrait fonctionner.

    --
    Jedaï

  14. #14
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 39
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par Lily_ Voir le message
    J'en suis donc restée au fork. Mais... ca ne semble pas fonctionner! En tout cas, le kill ne tue pas mon processus monprog.pl.
    tu ne peux pas récupérer le pid du script lancé par system, donc tu n'as aucune chance de le tuer ... enfin pas avec une méthode directe ...

    rappelle toi, quand tu clones ton prog, fork renvoie le pid du fils lorsque l'on est dans le père ... Il faut donc faire en sorte que ta routine "start" renvoie le pid pour qu'il puisse être passé à la routine stop, par exemple en renvoyant le pid lorsqu'on démarre le script, et 0 ou -1 lorsqu'on l'arrète ... donc tu fais un
    ce qui tuera le fils, et donc le script ...

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    Alors je n'ai pas réfléchi dans le détail à comment faire en sorte que ca fonctionne, mais je vois qu'il est est question d'utiliser la fonction "system" plutot que "exec". Ces 2 fonctions font la même chose , sauf que "system" execute déja un fork au préalable et que le processus parent attend dans ce cas la fin du processus fils pour continuer à s'executer :
    http://perldoc.perl.org/functions/system.html
    Donc peut etre que ca marcherait mieux avec un petit "exec" ?

  16. #16
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 39
    Points : 30
    Points
    30
    Par défaut
    Si on fait un appel à exec, le programme sera remplacé par la commande appelée ...

    Donc si on fork, on peut récupérer son pid, on fait un system, et lorsqu'on tue le fils, ça tue aussi l'appel système ...

    Maintenant reste à savoir ce qui se produira si on fork, puis si on fait un appel à exec ... Le fils sera remplacé par la commande appelée mais la question est : le pid de la commande appelée sera-t-il le même que celui du fils ???

  17. #17
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 4
    Points : 5
    Points
    5
    Par défaut
    Bon je donne l'exemple suivant si ca peut aider.
    C'est un menu qui permet d'appeler différents scripts.
    Quand le traitement associé au script est terminé, on re-affiche le menu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    #!d:/perl/bin/perl
     
    my $quit=0;
     
    while (!$quit) {
    print <<EOF;
     
     
     
    Menu de configuration des calculateurs
     
    1- Ajout d'un calculateur
    2- Suppression d'un calculateur
    3- Affichage de la liste des calculateurs
    4- Affichage des caractéristiques d'un calculateur
    5- Generation de la configuration calculateur
    6- Quitter
     
    EOF
     
    print "Rentrez votre choix et appuyer sur entree : \n";
    my $choix =<STDIN>;
     
    if ($choix=='1'){
       $pid = fork;
       if ($pid ==0 ){
       exec 'perl Conf_Calc_Ajout.pl';
       }
       else {
         wait;
       }
    }
    if ($choix=='2'){
       $pid = fork;
       if ($pid ==0 ){
       exec 'perl Conf_Calc_Suppr.pl';
       }
       else {
         wait;
       }
    }
    if ($choix=='3'){
       $pid = fork;
       if ($pid ==0 ){
       exec 'perl Conf_Calc_Liste.pl';
       }
       else {
         wait;
       }
    }
    if ($choix=='4'){
       $pid = fork;
       if ($pid ==0 ){
       exec 'perl Conf_Calc_Detail.pl';
       }
       else {
         wait;
       }
    }
    if ($choix=='5'){
       $pid = fork;
       if ($pid ==0 ){
       exec 'perl Conf_Calc_Gen.pl';
       }
       else {
         wait;
       }
    }
    if ($choix=='6'){
       print "Vous avez choisi de quitter";
       $quit=1;
       }
     
    sleep 1;
    }

  18. #18
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 39
    Points : 30
    Points
    30
    Par défaut
    Si tu as testé ta solution alors ça devrait correspondre aux attentes de mistinguette ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
       $pid = fork;
       if ($pid ==0 ){
       exec 'perl script.pl';   # ou system si ça ne marche pas
       }
       else {
         # Le père effectue sa tâche
     
         # Et celle ci terminée, il tue le fils, donc le script avec
         kill 9, $pid
       }
    j'ai quand même un léger doute au niveau du fonctionnement d'exec, puisqu'ici il faut pouvoir tuer le script lancé ...

  19. #19
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2007
    Messages : 12
    Points : 7
    Points
    7
    Par défaut
    Merci à tous pour vos réponses! C'est très sympa de vous être penché sur mon problème!

    Le problème est résolu! J'ai utilisé une méthode un peu différente pour le kill, car je dois le faire depuis une autre subroutine (bouton start et bouton stop). Et donc le pid ne fonctionnait pas, comme vous me l'avez justement fait remarquer! J'utilise un fichier temporaire et sa suppression entraine l'arret du processus fils. Tout fonctionne!

    Bonne fin de journée!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. "Piloter" script depuis un autre script
    Par Arcangedu31 dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 07/06/2013, 11h41
  2. Réponses: 0
    Dernier message: 19/12/2011, 15h51
  3. [MySQL] appeler un script depuis un autre serveur et retourner un lien
    Par taka10 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 12/01/2011, 14h45
  4. Appeler un autre script depuis un script
    Par Foub dans le forum ANT
    Réponses: 5
    Dernier message: 18/07/2007, 10h32
  5. Réponses: 15
    Dernier message: 22/12/2006, 15h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo