Perché non è il processo comincio con il sistema di Perl () un processo figlio?
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:
-
da uno script Perl, eseguire un'utilità della riga di comando che avvia un servizio. Le uscite di utilità, ma i soggiorni di servizio.
-
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.
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 ().