Frage

Perl-System () startet einen Prozess, aber bricht die Eltern / Kind-Beziehung?

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

Wenn ich test.pl laufen, findet es und druckt eine korrekte pid von test.sh. Aber waitpid () gibt -1 und test.pl beendet. Nach test.pl vorhanden ist, wird test.sh noch ausgeführt wird.

Es sieht aus wie test.sh kein Kind von test.pl ist, das bricht waitpid (). Warum passiert das und wie system () verhalten machen? Ist das, weil Perl Kinder automatisch löscht? Wenn ja, wie kann ich eine allgemeine Aufgabe lösen explizit auf ein Kind des Wartens?

Update:

Antworten unten vorschlagen, mit fork / exec. Das anfängliche Problem ist folgende:

  1. von einem Perl-Skript, führen Sie ein Befehlszeilenprogramm, das einen Dienst gestartet wird. Die Utility-Ausgänge, aber die Service-Aufenthalte.

  2. nach einiger Zeit finden, dass Service der pid und warten auf sie.

fork / exec führt dies nicht lösen, obwohl sie die Frage klärt.

War es hilfreich?

Lösung

Der test.sh Prozess ist nicht Ihr Kind Prozess. Die system() gegabelt eine Schale (die Ihr Kind), dass Shell ein Kind gegabelt, die das test.sh Programm lief. Die Hülle, die Ihr Kind war verlassen.

Andere Tipps

Was möchten Sie wahrscheinlich ist, etwas zu tun wie folgt aus:

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

Obwohl da der Shell-Skript in einer Endlosschleife ist, wird es für immer warten.

In der Regel sollten Sie manuell fork und exec, wenn Sie Perl nicht wollen helfen du bist raus. Es ist schwer, genau zu bestimmen, was Sie tun, aber ich dies denken Sie:

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

# parent
...
waitpid $pid, 0;

Ich persönlich lieber AnyEvent babysit lassen:

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

oder allgemeiner: http://github.com/jrockway/anyevent- subprocess / Baum / Master

Zur weiteren Erläuterung Liudvikas' Antwort -

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

(P) - process

Nach fork'ing und Ausführen des test.sh Skript die / bin / sh-Shell, die das Kind des Perl-Systemaufruf war, Ausfahrten und so erhalten Sie einen -1 Rückgabewert von waitpid ().

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top