2012-03-30 5 views
1

exec'ed hat Ich habe das folgende Design in einem Perl-Skript bekomme:prüfen, ob ein gegabeltes Kind noch in Perl

my $child_pid = fork; 
if(! $child_pid){ 
    # do some stuff... 
    exec($user_specified_command); 
else{ 
    # wait for child to exit 
    waitpid($child_pid, 0); 
} 
# Continue with the script 

Ich bin interessiert eine Warnung in den Eltern, wenn das Kind execs in immer, so dass ich einige Details über $user_specified_command bekommen kann (speziell um lsof zu verwenden, um herauszufinden, ob stdout in eine reguläre Datei umgeleitet wird). Das Ergebnis wäre so etwas wie diese:

my $child_pid = fork; 
if(! $child_pid){ 
    # do some stuff... 
    exec($user_specified_command); 
else{ 
    # wait until the child exec's 
    wait_child_exec(); 

    # do some stuff... 

    # wait for child to exit 
    waitpid($child_pid, 0); 
} 
# Continue with the script 

ich konnte Schleife und ps ausgegeben, bis der Name ändert grep, aber es scheint wie exec ein ernst genug Ereignis ist, dass es ein besserer Weg.

+0

Wäre es einfacher, wenn Sie sein die Rollen von Kind und Eltern ausgetauscht? Immerhin hat der Elternteil die PID des Kindes und kann auf dieser Basis ein Signal senden. – thb

+0

Wenn ich erwarte, dass "dieser" Prozess ein Signal vor dem Exec sendet, besteht die Möglichkeit, dass das Betriebssystem den Exec noch nicht verarbeitet hat, und mein Perl-Kram könnte vorzeitig passieren? – ajwood

+0

Ja, genau richtig. Ich hätte daran denken sollen, aber nicht. Also, auf Ihren Rat hin, ein anderer Gedanke: Könnten Sie einen Wrapper um $ user_specified_command programmieren? Der Wrapper würde zwei Befehlszeilenargumente erhalten: Erstens würde er die PID von "diesem" Prozess erhalten, so dass er das benötigte Signal senden könnte; Zweitens würde es $ user_specified_command erhalten, so dass es wüsste, welchen Befehl es umbrachte. Wenn dies das Timing-Problem nicht löst, ist mein Ansatz schlecht. Bitte beraten. – thb

Antwort

2

Ein allgemeiner Ansatz besteht darin, eine Pipe im Parent zu erstellen, die vom Kind geerbt wird, und den Elternblock (oder Poll) das Leseende der Pipe zu haben.

das Kind Unter der Annahme hat FD_CLOEXEC oder, besser, ein geeigneter Wert von $^F, die Forderung des Kindes exec() wird der Rohrschreibende und erzeugen ein EOF für die Eltern in der Nähe:

# Run a command in a child process, returning to the parent only after 
# the child process has called exec'd or, failing that, terminated. 
# 
# WARNING - this code not rigorously tested 
# 
sub spawn_patiently { 
    my ($rd, $wr); 

    return unless pipe($rd, $wr); 
    # XXX This assumes $^F is less than fileno($wr) 
    #  In practice, you'd want it to be less than fileno($rd), too 

    my $pid = fork(); 
    return unless defined $pid; 

    if (! $pid) { 
    exec @_; 
    die "exec: $!"; 
    } 

    # parent - wait for child to exec 
    close($wr); 
    read($rd, my $dummy, 1); 

    1; 
} 
Verwandte Themen