Domanda

Il sistema di Perl () avvia un processo, ma rompe il rapporto padre / figlio?

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

Quando eseguo test.pl, trova e stampa una corretta pid di test.sh. Ma waitpid () restituisce -1 ed esce test.pl. Dopo esistono test.pl, test.sh è ancora in esecuzione.

Sembra che test.sh non è un bambino di test.pl, che rompe waitpid (). Perché accade questo e come fare sistema () si comportano? È che, poiché il Perl cancella automaticamente i bambini? Se sì, come posso risolvere un compito generale di attesa su un bambino in modo esplicito?

Aggiornamento:

risposte di seguito suggeriscono utilizzando fork / exec. Il problema iniziale è questo:

  1. da uno script Perl, eseguire un'utilità della riga di comando che avvia un servizio. Le uscite di utilità, ma i soggiorni di servizio.

  2. dopo un certo tempo, scoprire che il servizio di PID e aspettare su di esso.

fork / exec non risolve questo, anche se risolve il problema.

È stato utile?

Soluzione

Il processo test.sh non è il vostro processo figlio. Il system() biforcuta un guscio (che è il vostro bambino), che la Shell biforcuta un bambino che correva il programma test.sh. Il guscio che era il bambino è uscito.

Altri suggerimenti

Quello che probabilmente vuole fare è qualcosa di simile a questo:

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

Anche se dal momento che lo script sia in un ciclo infinito, si attenderà per sempre.

In generale, si dovrebbe fork ed exec se non si vuole Perl per aiutare manualmente sei fuori. E 'difficile determinare esattamente quello che stai facendo, ma io pensa che si desidera in questo modo:

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

# parent
...
waitpid $pid, 0;

Personalmente, preferisco lasciare AnyEvent babysit:

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

O, più in generale: http://github.com/jrockway/anyevent- sottoprocesso / albero / master

Per spiegare ulteriormente risposta Liudvikas' -

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

(P) - process

Dopo fork'ing e l'esecuzione dello script test.sh la shell / bin / sh, che era il figlio della chiamata di sistema Perl, di uscire e in modo da ottenere un valore di ritorno -1 da waitpid ().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top