Question

système de Perl () démarre un processus, mais rompt la relation parent / enfant?

test.pl:

use POSIX;

system("./test.sh &");

my $pid = `ps -C test.sh -o pid=`;

print "pid: -$pid-\n";

waitpid($pid, 0);

test.sh:

while true
do
    sleep 1
done

Quand je lance test.pl, il trouve et imprime une pid correcte de test.sh. Mais waitpid () renvoie -1 et sort de test.pl. Après test.pl existent, test.sh est toujours en cours d'exécution.

On dirait que test.sh est pas un enfant de test.pl, qui brise waitpid (). Pourquoi cela se produit et comment rendre le système () se comporter? Est-ce parce que Perl efface automatiquement les enfants? Si oui, comment puis-je résoudre une tâche générale d'attendre un enfant explicitement?

Mise à jour:

réponses ci-dessous suggèrent avec fork / exec. Le problème initial est le suivant:

  1. à partir d'un script Perl, exécuter un utilitaire de ligne de commande qui démarre un service. Les sorties de services publics, mais les séjours de service.

  2. après un certain temps, constater que pid de service et attendre sur elle.

fork / exec ne résout pas, même si elle éclaircit la question.

Était-ce utile?

La solution

Le processus de test.sh n'est pas votre processus d'enfant. Le system() une coquille en forme de fourche (qui est votre enfant), cette coquille en forme de fourche un enfant qui a dirigé le programme de test.sh. La coquille qui était votre enfant est sorti.

Autres conseils

Qu'est-ce que vous voulez sans doute faire est quelque chose comme ceci:

my $pid = fork || exec './test.sh';
print "pid: -$pid-\n";
waitpid($pid, 0);

Bien que depuis le script shell est dans une boucle infinie, il attendra toujours.

En général, vous devez fourche manuellement et exec si vous ne voulez pas Perl pour aider tu sors. Il est difficile de déterminer exactement ce que vous faites, mais je pensez que vous voulez ceci:

my $pid = fork;
unless($pid){
    # child;
    exec(qw/sh test.sh/);
}

# parent
...
waitpid $pid, 0;

Personnellement, je préfère laisser AnyEvent garder les enfants:

my $done = AnyEvent->condvar;

my $pid = fork;

unless( $pid ) { ... }

my $w = AnyEvent->child (
   pid => $pid,
   cb  => sub {
      my ($pid, $status) = @_;
      warn "pid $pid exited with status $status";
      $done->send;
   },
);

$done->recv; # control resumes here when child exits

Ou, plus généralement: http://github.com/jrockway/anyevent- subprocess / arbre / maître

Pour expliquer plus en détail la réponse de Liudvikas -

system("./test.sh &")
 |
 |--> (P) /bin/sh (to run test.sh)
       |
       |--> (P) test.sh & (still running)

(P) - process

Après fork'ing et l'exécution du script test.sh le shell / bin / sh, qui était l'enfant de l'appel système Perl, les sorties et ainsi vous obtenez une valeur -1 de retour de waitpid ().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top